thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。或者说join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行。
方法:
t.join(); //使调用线程 t 在此之前执行完毕。
t.join(1000); //等待 t 线程,等待时间是1000毫秒
public class TestThreadJoin { public static void main(String[] args){ System.out.println("system start time:"+System.currentTimeMillis()); Thread A = new Thread(){ @Override public void run() { try { sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0;i<10;i++){ System.out.println("current thread :"+ Thread.currentThread().getName());} System.out.println("current thread :"+ Thread.currentThread().getName()); System.out.println("A thread execute end time :"+ System.currentTimeMillis()); } }; Thread B = new Thread(A); System.out.println("A name:"+A.getName()); System.out.println("B name:"+B.getName()); A.start(); B.start(); try { System.out.println("current thread in main:"+Thread.currentThread().getName()); B.join(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("main end time:"+System.currentTimeMillis()); } }
system start time:1466060949347 A name:Thread-0 B name:Thread-1 current thread in main:main main end time:1466060949403 current thread :Thread-1 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-1 current thread :Thread-0 current thread :Thread-1 current thread :Thread-1 A thread execute end time :1466060949553 A thread execute end time :1466060949553
先上一段JDK中代码:
/** * Waits at most {@code millis} milliseconds for this thread to * die. A timeout of {@code 0} means to wait forever. * <p> This implementation uses a loop of {@code this.wait} calls * conditioned on {@code this.isAlive}. As a thread terminates the * {@code this.notifyAll} method is invoked. It is recommended that * applications not use {@code wait}, {@code notify}, or * {@code notifyAll} on {@code Thread} instances. * @param millis * the time to wait in milliseconds * @throws IllegalArgumentException * if the value of {@code millis} is negative * @throws InterruptedException * if any thread has interrupted the current thread. The * <i>interrupted status</i> of the current thread is * cleared when this exception is thrown. */ public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
从代码上看,如果线程被生成了,但还未被起动,调用它的 join() 方法是没有作用的,将直接继续向下执行
Join方法实现是通过wait(小提示:Object 提供的方法)。 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程 ,比如退出后。这就意味着main 线程调用t.join时,必须能够拿到线程t对象的锁
class MyThread extends Thread {
public void run() {
System.out.println(getName() + "开始sleep" );
try {
Thread.sleep( 2000 );
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(getName() + "结束sleep" );
}
} public class TestWaitNotify {
public static void main(String[] args)
throws Exception {
Thread myThread = new MyThread();
myThread.start();
synchronized (myThread) {
myThread.wait();
}
System.out.println( "wait结束." );
}
} |
myThread执行结束后,main线程中的wait操作就自动退出了。程序里也并没有看到有notify/notifyAll调用。
如果将程序改成下面这样:
class MyThread extends Thread {
public void run() {
System.out.println(getName() + "开始sleep" );
try {
Thread.sleep( 2000 );
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(getName() + "结束sleep" );
}
} public class TestWaitNotify {
public static void main(String[] args)
throws Exception {
Thread myThread = new MyThread();
myThread.start();
Object tmp = new Object();
synchronized (tmp) {
tmp.wait();
}
System.out.println( "wait结束." );
}
} |
wait操作作用在一个独立的对象上,而不是像前面那样作用于线程对象上。这时程序就会一直wait下去。
给人直观的感觉,要么是发生了虚假唤醒,要么是线程在结束的时候做了些事情。经过查找,终于在JDK1.7 API文档的带参数的join方法上发现了蛛丝马迹!它是这么说的:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
也就是说join的实现方式大概如下:
while ( this .isAlive()) {
this .wait();
} |
当线程结束的时候会调用notifyAll方法来让join方法返回,这个调用也影响了我们的应用程序。这也是为什么wait调用一定要放到一个循环中的因素之一。文档中也写明了不推荐我们的应用在Thread实例上调用wait, notify, or notifyAll。
在JDK1.7之前的API文档中是找不到这些描述的。碰到这样的问题只能去找JVM源码了。且在JDK1.7的文档中,这个信息还是出现在join方法上,调用wait/notify出问题的时候,如果事先不了解这个机制,又怎么会去看join方法的API呢!由此可见,一份好的JAVA DOC文档的重要性。
相关推荐
是第一次在C#中接触Thread,自己研究了一下其中Thread.Join()这个方法,下面谈谈自己的理解。 Thread.Join()在MSDN中的解释很模糊:Blocks the calling thread until a thread terminates 有两个主要问题: ...
CountDownLatch与thread.join()的区别
线程创建,线程等待与清除,thread_clean.c,thread_create.c,thread_create.c,thread_exit_struct.c,thread_id.c,thread_int.c, thread_join.c, thread_join.c, thread_string.c, thread_struct.c
本文实例讲述了C#多线程之Thread中Thread.Join()函数用法。分享给大家供大家参考。具体分析如下: Thread.Join()在MSDN中的解释:Blocks the calling thread until a thread terminates 当NewThread调用Join方法的...
主要介绍了c++11中关于std::thread的join详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
主要介绍了java 中Thread.join()的使用方法的相关资料,需要的朋友可以参考下
主要介绍了Java中Thread.join()的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
主要介绍了JAVA CountDownLatch与thread-join()的区别解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
join() 定义在Thread.java中。 join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行。这句话可能有点晦涩,我们还是通过例子去理解
主要介绍了Java之Thread的join方法,实例形式讲述了join方法的应用,需要的朋友可以参考下
1,简介 C++11中加入了<thread>头文件,此头文件主要声明了std::thread线程类。C++11的标准类std::thread对线程进行了封装,定义了C++11标准中的一些表示线程的...缺省构造的thread对象、已经完成join的thread对象、已
本文对java Thread中join()方法进行介绍,join()的作用是让“主线程”等待“子线程”结束之后才能继续运行,大家参考使用吧
普通线程的创建,通过 委托ThreadStart对应的函数来执行相关操作; 通过线程池,可以直接从池中查找出空闲线程,让它执行委托WaitCallback对应函数来执行相关操作。使用时要与AutoResetEvent来并用,以在线程结束时...
本篇文章主要介绍了浅谈Java线程Thread.join方法解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
线程可以通过 join() 方法等待线程的退出。 5. 线程的优先级 Thread 类提供了 setThreadPriority() 方法来设置线程的优先级,优先级范围从 1 到 99,其中 99 是实时优先级,其他值是普通优先级。线程的优先级可以...
c++11多线程库的使用,主要介绍了thread类中的构造函数 join函数和detach函数的使用方式
Thread.join() 作用为阻塞主线程,即在子线程未返回的时候,主线程等待其返回然后再继续执行. join不能与start在循环里连用 以下为错误代码,代码创建了5个线程,然后用一个循环激活线程,激活之后令其阻塞主线程. ...
本文实例讲述了Python中threading模块join函数用法。分享给大家供大家参考。具体分析如下: ... thread_arr[i].join() 此处join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束