java concurrency 线程_Java Concurrency - 线程的基础操作

创建线程

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

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

public class MyJob extendsThread {

@Overridepublic voidrun() {

System.out.println("Hello Thread");

}public static voidmain(String[] args) {

Thread thread= newMyJob();

thread.start();

}

}

实现 java.lang.Runnable 接口,然后在创建 Thread 实例时传入 Runnable 参数。

public class MyJob implementsRunnable {

@Overridepublic voidrun() {

System.out.println("Hello Thread");

}public static voidmain(String[] args) {

Thread thread= new Thread(newMyJob());

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 voidmain(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) throwsException {

Thread task= new Thread(newRunnable() {public voidrun() {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 implementsRunnable {private String initPath; //Initial path for the search

private String fileName; //Name of the file we are searching for

publicFileSearch(String initPath, String fileName) {this.initPath =initPath;this.fileName =fileName;

}/*** Main method of the class*/@Overridepublic voidrun() {

File file= newFile(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 voidcleanResources() {

}/*** Method that process a directory

*

*@paramfile

* : Directory to process

*@throwsInterruptedException

* : If the thread is interrupted*/

private void directoryProcess(File file) throwsInterruptedException {//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 newInterruptedException();

}

}/*** Method that process a File

*

*@paramfile

* : File to process

*@throwsInterruptedException

* : If the thread is interrupted*/

private void fileProcess(File file) throwsInterruptedException {//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 newInterruptedException();

}

}/*** 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

*@paramargs*/

public static voidmain(String[] args) {//Creates the Runnable object and the Thread to run it

FileSearch searcher=new FileSearch("C:\\","CHAINLOG.log.2016092210");

Thread thread=newThread(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) throwsException {

Thread dataSourcesLoader= new Thread(newRunnable() {public voidrun() {

System.out.printf("Begining data sources loading: %s\n",newDate());try{

TimeUnit.SECONDS.sleep(4);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.printf("Data sources loading has finished: %s\n",newDate());

}

});

Thread networkConnectionsLoader= new Thread(newRunnable() {

@Overridepublic voidrun() {

System.out.printf("Begining network connections loading: %s\n",newDate());try{

TimeUnit.SECONDS.sleep(6);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.printf("Network connections loading has finished: %s\n",newDate());

}

});

dataSourcesLoader.start();

networkConnectionsLoader.start();

dataSourcesLoader.join();

networkConnectionsLoader.join();

System.out.printf("Main: Configuration has been loaded: %s\n",newDate());

}

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

守护进程

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值