http://www.journaldev.com/1024/java-thread-join-example
Java Thread join():本函数用来使线程暂停,转让控制权,这里的暂停指的是暂停当前,转让给x.join(),x
方便的理解记忆:join();----老衲加入了!!!!老衲现在最大,或者老衲在规定的时间最大!!我有控制权。
public final void join(): 这个java线程连接方法使得当前线程处于等待过程,知道线程死亡。如果线程被中断,它抛出Interrupted Exception。
public final synchronized void join(long millis): 这个java线程连接方法用于使得线程等待指定的时间,单位毫秒。由于线程执行取决于操作系统实现,它并不能保证当前线程将执行等待的时间。
package com.journaldev.threads;
public class ThreadJoinExample {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable(), "t1");
Thread t2 = new Thread(new MyRunnable(), "t2");
Thread t3 = new Thread(new MyRunnable(), "t3");
t1.start();
//start second thread after waiting for 2 seconds or if it's dead
try {
t1.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
//start third thread only when first thread is dead
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
//let all threads finish execution before finishing main thread
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("All threads are dead, exiting main thread");
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("Thread started:::"+Thread.currentThread().getName());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread ended:::"+Thread.currentThread().getName());
}
}
结果:
Thread started:::t1//t1.join(2000);t1线程获得控制权力,时间2S;----所以t1start----- Thread.sleep(4000);----超过时间交出控制权
Thread started:::t2//------回到主线程----t2 start ----------执行t1.join()-----t1加入,重获新生!!!!-----回到run()继续执行-----输出t1 end----死亡----返回主线程Thread ended:::t1
Thread started:::t3//此刻 t3.start();
Thread ended:::t2// -----t1,t2,t3---依次join()------t1已经亡,轮到t2-----t2继续上次执行,run()---t2 end-----
Thread ended:::t3// -同理t3------交给main----main end
All threads are dead, exiting main thread
(断点运行,有助于理解)
2.延伸:
即join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。
bt.join();//意思:bt加入了,此刻转让控制权,必须等待bt对象线程执行完毕才能继续向下!!!!
class BThread extends Thread {
public BThread() {
super("[BThread] Thread");
};
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " loop at " + i);
Thread.sleep(1000);
}
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}
class AThread extends Thread {
BThread bt;
public AThread(BThread bt) {
super("[AThread] Thread");
this.bt = bt;
}
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
bt.join();
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}
public class TestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
BThread bt = new BThread();
AThread at = new AThread(bt);
try {
bt.start();
Thread.sleep(2000);
at.start();
at.join();
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!");
}
}
可能的结果:
或者:(系统决定时间片分配)main start. //主线程起动,因为调用了at.join(),要等到at结束了,此线程才能向下执行。 [BThread] Thread start. [BThread] Thread loop at 0 [BThread] Thread loop at 1 [AThread] Thread start. //线程at启动,因为调用bt.join(),等到bt结束了才向下执行。 [BThread] Thread loop at 2 [BThread] Thread loop at 3 [BThread] Thread loop at 4 [BThread] Thread end. [AThread] Thread end. // 线程AThread在bt.join();阻塞处起动,向下继续执行的结果 main end! //线程AThread结束,此线程在at.join();阻塞处起动,向下继续执行的结果。
main start.
[BThread] Thread start.
[BThread] Thread loop at 0
[BThread] Thread loop at 1
[BThread] Thread loop at 2
[AThread] Thread start.
[BThread] Thread loop at 3
[BThread] Thread loop at 4
[BThread] Thread end.
[AThread] Thread end.
main end!
更改代码:
public class TestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
BThread bt = new BThread();
AThread at = new AThread(bt);
try {
bt.start();
Thread.sleep(2000);//此处thread是main线程
at.start();
//at.join(); //在此处注释掉对join()的调用
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!");
}
}
结果:
main start. // 主线程起动,因为Thread.sleep(2000),主线程没有马上结束; [BThread] Thread start. //线程BThread起动 [BThread] Thread loop at 0 [BThread] Thread loop at 1 main end! // 在sleep两秒后主线程结束,AThread执行的bt.join();并不会影响到主线程。 [AThread] Thread start. //线程at起动,因为调用了bt.join(),等到bt结束了,此线程才向下执行。 [BThread] Thread loop at 2 [BThread] Thread loop at 3 [BThread] Thread loop at 4 [BThread] Thread end. //线程BThread结束了 [AThread] Thread end. // 线程AThread在bt.join();阻塞处起动,向下继续执行的结果