API:

join

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


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

join

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


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

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

join

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


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

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

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

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

解析

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 2014
Data sources loading has finished: Fri Nov 14 14:27:35 CST 2014
Main: 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 2014
Beginning data sources loading: Fri Nov 14 14:28:33 CST 2014
Data 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 2014
Main: Configuration has been loaded: Fri Nov 14 14:35:48 CST 2014
Data 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 2014
Beginning network connect loading: Fri Nov 14 14:39:20 CST 2014
Data sources loading has finished: Fri Nov 14 14:39:24 CST 2014
Main: Configuration has been loaded: Fri Nov 14 14:39:26 CST 2014
Network 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 2014
Beginning network connect loading: Fri Nov 14 14:41:21 CST 2014
Data sources loading has finished: Fri Nov 14 14:41:25 CST 2014
Network connect loading has finished: Fri Nov 14 14:41:27 CST 2014
Main: Configuration has been loaded: Fri Nov 14 14:41:27 CST 2014</span>

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

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

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

Thread.join()分析方法的更多相关文章

  1. 关于C#中Thread.Join()的一点理解

    原文地址:http://www.cnblogs.com/slikyn/articles/1525940.html 今天是第一次在C#中接触Thread,自己研究了一下其中Thread.Join()这个 ...

  2. C#多线程Thread.Join()的详解

    class TestThread { private static void FirstThreadFun() { ; i < ; i++) { Console.WriteLine(Thread ...

  3. Thread.Join()的详解

    什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?线程是程序中的一个执行流,每个线程都有自己的专有寄 ...

  4. C#多线程详解(一) Thread.Join()的详解

    bicabo   C#多线程详解(一) Thread.Join()的详解 什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程 ...

  5. Thread.join()方法

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B.t.join() ...

  6. Java Thread.join()方法

    一.使用方式. join是Thread类的一个方法,启动线程后直接调用,例如: Thread t = new AThread(); t.start(); t.join(); 二.为什么要用join() ...

  7. JAVA THREAD.JOIN方法详解

    一.使用方式. join是Thread类的一个方法,启动线程后直接调用,例如: Thread t = new AThread(); t.start(); t.join(); 二.为什么要用join() ...

  8. Thread.Join 和 Task.Wait 方法

    这两个方法 可以说是类似的功能,都是对当前任务进行等待阻塞,执行完毕后再进行后续处理 talk is cheap, show you code,下面一个是异步执行,一个是加了阻塞,可以对比不同执行结果 ...

  9. 多线程--Thread.join方法

    在Thread类的Api中,Join的作用是让当前线程等待目标线程结束之后才继续执行. thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.  比如在线程B ...

随机推荐

  1. 从O2O体验活动看华硕平板也“来电”新融合理念

          随着平板电脑的普及,用户对平板的要求也变得越来越高,且这种要求已经逐渐从单纯的性能方面拓展到全方位的功能方面,尤其在通讯.社交.娱乐等层面,平板迫切需要满足用户日益增长的需求.       ...

  2. C# split字符串 依据1个或多个空格

    实例场景.对于字符串:"AAAA AAA        BBBB BBB BBB        CCCCCCCC". 1. 分隔为 "AAAA AAA" . & ...

  3. table明明设置了固定值

    IE真的快把我搞死了 0.0 可爱的迷人的让人醉了的IE你真棒 今天用表格写一个4列的表格 要实现的效果大概是这种 确有用普通浏览器都没有问题 非常easy明了的一个表格嘛!用IE8下面的看就成这样子 ...

  4. ogre sample分析(一)

    ogre自带了一些例子,逐个过一遍并自己动手做一些调整 1 Sample_BezierPatch:这个例子直接用数值来构造顶点缓存并创建entity,这种方法一般只能创建简单对象,本人以为复杂对象顶点 ...

  5. linux下的开源移动图像监测程序--motion编译与配置

    前几天在网上偶然看到一篇博客,是利用linxu下的开源的motion搭建嵌入式视频动态监控系统,感觉很好很强大于,是就想自己编译移植一下试试. 所谓移动图像监测,简单来说就是利用摄像头定点监测某个区域 ...

  6. mysql导出和导入数据库

    出口 在dos计划,切换到mysql按照该文件夹bin下一个.输入以下命令 mysqldump -u root -p nxu_life > nxu_life2.sql 运行完毕后,就能够看到在b ...

  7. WPF案例(二)模拟Apple OS 界面前后180度反转

    原文:WPF案例(二)模拟Apple OS 界面前后180度反转 我们在设计应用程序界面的时候,为了充分利用界面空间,住住需要灵活的界面布局方式,比如可以在界面正面空间上定义一个Chart,背面空间上 ...

  8. adt-bundle更新eclipse,以及搭建android环境

    曾经开发一直去android官网下载adt-bundle的.里面已经包括了eclipse和android SDK,搭建android环境特别方便,仅仅须要3步:1.下载并安装jdk(也就是jar se ...

  9. 局部权重线性回归(Locally weighted linear regression)

    在线性回归中,因为对參数个数选择的问题是在问题求解之前已经确定好的,因此參数的个数不能非常好的确定,假设參数个数过少可能拟合度不好,产生欠拟合(underfitting)问题,或者參数过多,使得函数过 ...

  10. 依赖注入(DI)

    依赖注入(DI)   IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用“好莱坞原则”是应用程序以被动的方式实现对流程的定制.我们可以采用若干设 ...