创建线程

在 Java 中,创建线程有两种方式:

  • 继承 java.lang.Thread 类,重写 run 方法。

    public class MyJob extends Thread {
    
        @Override
    public void run() {
    System.out.println("Hello Thread");
    } public static void main(String[] args) {
    Thread thread = new MyJob();
    thread.start();
    }
    }
  • 实现 java.lang.Runnable 接口,然后在创建 Thread 实例时传入 Runnable 参数。
    public class MyJob implements Runnable {
    @Override
    public void run() {
    System.out.println("Hello Thread");
    } public static void main(String[] args) {
    Thread thread = new Thread(new MyJob());
    thread.start();
    }
    }

获取和设置线程信息

java.lang.Thread 类中的几个信息字段帮助我们来识别一个线程、观察线程的状态或是控制线程的优先级:

  • Id: 线程的 ID,每个线程拥有一个唯一的标识。
  • Name: 线程的名称。
  • Priority: 线程的优先级。优先级的范围是 1~10,值越大优先级越高。
  • State: 线程的状态。在 Java 中,线程有六种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING 和 TERMINATED。

上述的属性 java.lang.Thread 类都提供 getter 方法以获取线程的信息,其中 Id 和 State 是不可代码控制修改的,也不提供 setter 方法。

获取当前正在运行的线程

java.lang.Thread 类提供一个静态方法 currentThread(),该方法返回当前正在运行的线程。

public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()); // main
}

线程休眠

Thread 类的 sleep() 方法接收一个 long 参数 milliseconds,使得当前正在运行的线程休眠 milliseconds 毫秒。

TimeUnit 类同样提供提供 sleep() 方法支持线程休眠。它接收各种时间单位并将其转换成微秒。

try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}

线程中断

有时候,我们需要在线程任务执行完毕前取消线程任务,例如当下载文件超时时取消下载任务。当 interrupt() 方法被调用时,线程的中断状态被置为 true,但是线程并不会终止。可以利用 isInterrupted 方法检测线程是否中断,并以此对线程进行控制。

public static void main(String[] args) throws Exception {

    Thread task = new Thread(new Runnable() {
public void run() {
int num = 2;
while (!Thread.currentThread().isInterrupted()) {
if (Primes.isPrime(num)) {
System.out.println(String.format("Number %d is Prime", num));
}
num++;
}
}
}); task.start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
task.interrupt(); }

Thread 类还提供一个静态的 interrupted() 方法来判断当前正在运行的线程是否中断。但是 interrupted() 与 isInterrupted() 有些差异:isInterrupted() 方法不会修改中断状态;而 interrupted() 方法会将中断状态置为 true。

有时线程执行的任务十分复杂,使用异常控制会比条件控制更加可取。

/**
* This class search for files with a name in a directory
*/
public class FileSearch implements Runnable { private String initPath; // Initial path for the search
private String fileName; // Name of the file we are searching for public FileSearch(String initPath, String fileName) {
this.initPath = initPath;
this.fileName = fileName;
} /**
* Main method of the class
*/
@Override
public void run() {
File file = new File(initPath);
if (file.isDirectory()) {
try {
directoryProcess(file);
} catch (InterruptedException e) {
System.out.printf("%s: The search has been interrupted", Thread.currentThread().getName());
cleanResources();
}
}
} /**
* Method for cleaning the resources. In this case, is empty
*/
private void cleanResources() { } /**
* Method that process a directory
*
* @param file
* : Directory to process
* @throws InterruptedException
* : If the thread is interrupted
*/
private void directoryProcess(File file) throws InterruptedException { // Get the content of the directory
File list[] = file.listFiles();
if (list != null) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
// If is a directory, process it
directoryProcess(list[i]);
} else {
// If is a file, process it
fileProcess(list[i]);
}
}
}
// Check the interruption
if (Thread.interrupted()) {
throw new InterruptedException();
}
} /**
* Method that process a File
*
* @param file
* : File to process
* @throws InterruptedException
* : If the thread is interrupted
*/
private void fileProcess(File file) throws InterruptedException {
// Check the name
if (file.getName().equals(fileName)) {
System.out.printf("%s : %s\n", Thread.currentThread().getName() ,file.getAbsolutePath());
} // Check the interruption
if (Thread.interrupted()) {
throw new InterruptedException();
}
} /**
* Main method of the core. Search for the autoexect.bat file
* on the Windows root folder and its subfolders during ten seconds
* and then, interrupts the Thread
* @param args
*/
public static void main(String[] args) {
// Creates the Runnable object and the Thread to run it
FileSearch searcher=new FileSearch("C:\\","CHAINLOG.log.2016092210");
Thread thread=new Thread(searcher); // Starts the Thread
thread.start(); // Wait for ten seconds
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} // Interrupts the thread
thread.interrupt();
}
}

join - 等待线程结束

在某些情况下,需要等待某一线程执行完毕后当前的线程才能继续执行,例如等待某个资源初始化完毕后才能执行后续的操作。 Thread 类提供了 join() 方法来实现此功能。当在线程 thread1 中调用 thread2.join() 方法,那么 thread1 线程将会挂起直至线程 thread2 结束。

Example:

public static void main(String[] args) throws Exception {

    Thread dataSourcesLoader = new Thread(new Runnable() {
public void run() {
System.out.printf("Begining data sources loading: %s\n",new Date());
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Data sources loading has finished: %s\n",new Date());
}
}); Thread networkConnectionsLoader = new Thread(new Runnable() {
@Override
public void run() {
System.out.printf("Begining network connections loading: %s\n",new Date());
try {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Network connections loading has finished: %s\n",new Date());
}
}); dataSourcesLoader.start();
networkConnectionsLoader.start(); dataSourcesLoader.join();
networkConnectionsLoader.join();
System.out.printf("Main: Configuration has been loaded: %s\n",new Date());
}

jion 还有两个重载的方法:join (long milliseconds) 和 join (long milliseconds, long nanos)。第一个方法接收一个 long 参数 milliseconds,如果在线程 thread1 中调用代码 thread2.join(1000),则 thread1 线程挂起直至当 thread2 线程执行完毕;或者当 1000 毫秒过去后,即使 thread2 仍未执行完毕,thread1 依然停止挂起,继续执行。

守护进程

在线程启动前调用 setDaemon(true) 可以将线程设置为守护进程。

Java Concurrency - 线程的基础操作的更多相关文章

  1. Java Concurrency - 线程执行器

    Usually, when you develop a simple, concurrent-programming application in Java, you create some Runn ...

  2. 原创】Java并发编程系列2:线程概念与基础操作

    [原创]Java并发编程系列2:线程概念与基础操作 伟大的理想只有经过忘我的斗争和牺牲才能胜利实现. 本篇为[Dali王的技术博客]Java并发编程系列第二篇,讲讲有关线程的那些事儿.主要内容是如下这 ...

  3. 深入浅出 Java Concurrency (34): 线程池 part 7 线程池的实现及原理 (2)[转]

    线程池任务执行流程 我们从一个API开始接触Executor是如何处理任务队列的. java.util.concurrent.Executor.execute(Runnable) Executes t ...

  4. Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步

    Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步 一.概述     PV操作是对信号量进行的操作.     进程同步是指在并发进程之间存在一种制约关系,一个进程的执行依赖另一个进程的消 ...

  5. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

  6. 深入浅出 Java Concurrency (35): 线程池 part 8 线程池的实现及原理 (3)[转]

    线程池任务执行结果 这一节来探讨下线程池中任务执行的结果以及如何阻塞线程.取消任务等等. 1 package info.imxylz.study.concurrency.future;2 3 publ ...

  7. 深入浅出 Java Concurrency (33): 线程池 part 6 线程池的实现及原理 (1)[转]

    线程池数据结构与线程构造方法 由于已经看到了ThreadPoolExecutor的源码,因此很容易就看到了ThreadPoolExecutor线程池的数据结构.图1描述了这种数据结构. 图1 Thre ...

  8. 深入浅出 Java Concurrency (28): 线程池 part 1 简介[转]

    从这一节开始正式进入线程池的部分.其实整个体系已经拖了很长的时间,因此后面的章节会加快速度,甚至只是一个半成品或者简单化,以后有时间的慢慢补充.完善. 其实线程池是并发包里面很重要的一部分,在实际情况 ...

  9. Java 基础 多线程和线程池基础

    一,多线程 1.1 多线程介绍 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是进程中的一个执行单元,负 ...

随机推荐

  1. 微信读书 iOS 性能优化总结

    微信读书作为一款阅读类的新产品,目前还处于快速迭代,不断尝试的过程中,性能问题也在业务的不断累积中逐渐体现出来.最近的 1.3.0 版本发布后,关于性能问题的用户反馈逐渐增多,为此,团队开始做一些针对 ...

  2. ID生成器的一种可扩展实现方案

    ID生成器主要为了解决业务程序生成记录ID的场景,而一个好的ID生成器肯定要满足扩展性好.并发性好的特点,本文下面介绍一种满足上述特点的实现方案. 此方案的核心思想是:每次需要扩容机器时,将每个节点维 ...

  3. thttpd的定时器

    运用了static函数实现文件封装 提升变量访问效率的关键字register,该关键字暗示该变量可能被频繁访问,如果可能,请将值存放在寄存器中 内存集中管理,每个节点在取消后并没有立即释放内存,而是调 ...

  4. C++的辅助工具介绍

    1 文档类  (1) Doxygen  参考站点:http://www.doxygen.org  Doxygen是一种适合C风格语言(如C++.C.IDL.Java甚至包括C#和PHP)的.开放源码的 ...

  5. centos6.5下Python IDE开发环境搭建

    自由不是想做什么就做什么,而是想不做什么就不做什么.        ---摘抄于2016/11/30晚 之前学习了一段时间的Python,但所有部署都在windows上.正赶上最近在学习liux,以后 ...

  6. ADO.NET 快速入门(六):读写 XML

    ADO.NET 和 DataSet 可以读写 XML Schema 和 XML.获取更多信息,请参考 How do I...Use XML and the DataSet?   DataSet 的 S ...

  7. stl lower_bound upper_bound binary_search equal_range

    自己按照stl实现了一个:   http://www.cplusplus.com/reference/algorithm/binary_search/ 这里有个注释,如何判断两个元素相同: Two e ...

  8. PHP+MySQL多语句执行<转自wooyun>

    发起这个帖子,估计就很多人看到题目就表示不屑了.一直以来PHP+MySQL环境下,无论是写程序或者是注入攻击,是无法多语句执行的,这么广为人知的常识,没理由会有人不知道.可权威就是用来被挑战的,常识也 ...

  9. CDOJ 482 Charitable Exchange bfs

    Charitable Exchange Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/s ...

  10. Codeforces Gym 100523K K - Cross Spider 计算几何,判断是否n点共面

    K - Cross SpiderTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/v ...