博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Thread.join()分析方法
阅读量:6923 次
发布时间:2019-06-27

本文共 5551 字,大约阅读时间需要 18 分钟。

API:

join

public final void join()                throws
等待该线程终止。

抛出:
- 假设不论什么线程中断了当前线程。当抛出该异常时,当前线程的
中断状态 被清除。

join

public final void join(long millis)                throws
等待该线程终止的时间最长为
millis 毫秒。超时为
0 意味着要一直等下去。

參数:
millis - 以毫秒为单位的等待时间。
抛出:
- 假设不论什么线程中断了当前线程。

当抛出该异常时,当前线程的中断状态 被清除。

join

public final void join(long millis,                       int nanos)                throws
等待该线程终止的时间最长为
millis 毫秒 +
nanos 纳秒。

參数:
millis - 以毫秒为单位的等待时间。

nanos - 要等待的 0-999999 附加纳秒。

抛出:
- 假设 millis 值为负,则 nanos 的值不在 0-999999 范围内。
- 假设不论什么线程中断了当前线程。

当抛出该异常时。当前线程的中断状态 被清除。

解析

Thread.join()。是用来指定当前主线程等待其它线程运行完成后。再来继续运行Thread.join()后面的代码

例1:

package com.example;import java.util.Date;import java.util.concurrent.TimeUnit;public class DataSourcesLoader implements Runnable{	@Override	public void run() {		System.out.printf("Beginning 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());	}	public static void main(String[] args){		DataSourcesLoader dsLoader = new DataSourcesLoader();	    Thread thread1 = new Thread(dsLoader,"DataSourceThread");	    	    thread1.start();	    	    try {	        thread1.join();	      } catch (InterruptedException e) {	        e.printStackTrace();	      }	      	      System.out.printf("Main: Configuration has been loaded: %s\n",new Date());	}}
运行结果:

Beginning data sources loading: Fri Nov 14 14:27:31 CST 2014Data sources loading has finished: Fri Nov 14 14:27:35 CST 2014Main: Configuration has been loaded: Fri Nov 14 14:27:35 CST 2014
假设去掉thread1.join(),运行的结果例如以下:

Main: Configuration has been loaded: Fri Nov 14 14:28:33 CST 2014Beginning data sources loading: Fri Nov 14 14:28:33 CST 2014Data sources loading has finished: Fri Nov 14 14:28:37 CST 2014
通过结果。就能够非常明显的说明上面红字的部分:“
再来继续运行Thread.join()后面的代码

例2:

package com.example;import java.util.Date;import java.util.concurrent.TimeUnit;public class DataSourcesLoader implements Runnable{	@Override	public void run() {		System.out.printf("Beginning 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());	}	public static void main(String[] args){		DataSourcesLoader dsLoader = new DataSourcesLoader();	    Thread thread1 = new Thread(dsLoader,"DataSourceThread");	    	    thread1.start();	    	    try {	        thread1.join(3000);	      } catch (InterruptedException e) {	        e.printStackTrace();	      }	      	      System.out.printf("Main: Configuration has been loaded: %s\n",new Date());	}}
这里使用的是:
thread1.join(3000);
这句话的意思是,仅仅要满足以下2个条件中的一个时,主线程就会继续运行thread.join()后面的代码:

条件1:thread1 运行完成。

条件2:已经等待 thread1 运行了3000ms.

样例中。thread1 自身的运行时间是4s。而设置的等待时间是3s,所以得到的运行结果例如以下。thread1还没有运行完,主线程就開始运行后面的代码。由于 thread1 等待的时间已经超时了:

Beginning data sources loading: Fri Nov 14 14:35:45 CST 2014Main: Configuration has been loaded: Fri Nov 14 14:35:48 CST 2014Data sources loading has finished: Fri Nov 14 14:35:49 CST 2014

那么结合上面的2个样例。我们能够判断出以下代码的运行结果了:

例3:

package com.example;import java.util.Date;import java.util.concurrent.TimeUnit;public class DataSourcesLoader implements Runnable{	@Override	public void run() {		System.out.printf("Beginning 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());	}}

package com.example;import java.util.Date;import java.util.concurrent.TimeUnit;public class NetworkConnectionsLoader implements Runnable{	@Override	public void run() {		System.out.printf("Beginning network connect loading: %s\n",new Date());	    try {	      TimeUnit.SECONDS.sleep(6);	    } catch (InterruptedException e) {	      e.printStackTrace();	    }	    System.out.printf("Network connect loading has finished: %s\n",new Date());			}		public static void main(String[] args){		DataSourcesLoader dsLoader = new DataSourcesLoader();	    Thread thread1 = new Thread(dsLoader,"DataSourceThread");	    	    NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();	    Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoader");	    	    thread1.start();	    thread2.start(); 	    	    try {	        thread1.join();	        thread2.join(1900);	      } catch (InterruptedException e) {	        e.printStackTrace();	      }	      	      System.out.printf("Main: Configuration has been loaded: %s\n",new Date());	}}
运行结果:

Beginning data sources loading: Fri Nov 14 14:39:20 CST 2014Beginning network connect loading: Fri Nov 14 14:39:20 CST 2014Data sources loading has finished: Fri Nov 14 14:39:24 CST 2014Main: Configuration has been loaded: Fri Nov 14 14:39:26 CST 2014Network connect loading has finished: Fri Nov 14 14:39:26 CST 2014
注意:假设把例3的 thread2.join(1900) 部分改动为:

thread2.join(3000);
结果会和上面的一样吗?

依据我最開始指出的“
Thread.join()。是用来指定当前主线程等待其它线程运行完成后,再来继续运行Thread.join()后面的代码

我们能够看到,运行结果会有区别:

Beginning data sources loading: Fri Nov 14 14:41:21 CST 2014Beginning network connect loading: Fri Nov 14 14:41:21 CST 2014Data sources loading has finished: Fri Nov 14 14:41:25 CST 2014Network connect loading has finished: Fri Nov 14 14:41:27 CST 2014Main: Configuration has been loaded: Fri Nov 14 14:41:27 CST 2014

至于为什么会有这个区别,我上面也已经说明了,我想这个应该不难理解。

PS:代码部分截取来自《Java 7 Concurrency Cookbook》

版权声明:本文博客原创文章。博客,未经同意,不得转载。

你可能感兴趣的文章
学习Python第一天!(2)
查看>>
理不清的网络基础知识(00)
查看>>
在Oracle 11g中用看Oracle的共享内存段---------IPCS
查看>>
如何提高PUE值 数据中心能耗详解
查看>>
我的友情链接
查看>>
hibernateTemplate类的使用-总结
查看>>
PHP生成随机的HTML颜色代码
查看>>
python最简单的发邮件方式(不带附件)
查看>>
maven第二节-maven基础-依赖管理
查看>>
通过脚本加hosts.deny文件阻止防***
查看>>
javascript函数的3种定义方式
查看>>
ORA-12578: TNS:wallet open failed
查看>>
快收藏!高手Linux运维管理必备工具大全,你会吗?
查看>>
Linux下Redis服务安全加固
查看>>
我的友情链接
查看>>
Dockerfile构建简单的mysql
查看>>
nutch介绍和安装配置
查看>>
Linux下的tar压缩解压缩命令详解
查看>>
JDK环境变量配置
查看>>
AKKA入门
查看>>