在大多数状况下,主线程建立并启动子线程,若是子线程中要进行大量的耗时计算,主线程每每会在子线程结束以前结束掉。如果主线程想要等待子线程执行完成以后再结束,则必须用到方法join().java
方法join()的做用为:等待线程对象销毁。this
首先先看一个join方法的例子线程
public class MyThread extends Thread { private static int number = 0; public void run(){ while(number < 1000){ number++; } } public static void main(String [] args){ MyThread t1 = new MyThread(); t1.start(); t1.join(); System.out.println(number); } } 运行结果:1000
在此例中,由于在当前线程------主线程中调用了t1线程的join方法,因此主线程必须等到子线程结束以后才能够继续运行。code
方法join的做用是使所属的线程对象x正常执行run方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁以后再继续进行线程z后面的代码。对象
方法join具备使线程排队运行的做用,有些相似于同步效果。但join与synchronized的区别是:join方法在内部使用wait方法进行等待,而synchronized关键字使用的是对象监视器原理做为同步。同步
若join方法遇到interrupt方法,则当前线程会抛出异常。即:在join过程当中,若是当前线程被打断,则当前线程出现异常。it
public class ThreadA extends Thread { public void run(){ int i = 0; while(true) { i++; } } } public class ThreadB extends Thread { public void run(){ try{ Thread a = new ThreadA(); a.start(); a.join(); }catch(InterruptedException e){ System.out.println("catch"); } } } public class ThreadC extends Thread { private ThreadB b; public ThreadC(ThreadB b){ this.b = b; } public void run(){ b.interrupt(); } } public class Run { public static void main(String [] args){ ThreadB b = new ThreadB(); b.start(); Thread.sleep(5000); ThreadC c = new ThreadC(b); c.start(); } } 运行结果:catch
分析:在当前线程join过程(即在当前线程中调用了join方法)中时,当前线程b又调用了interrupt方法,因此抛出异常。可是a线程仍然一直在运行。io
方法join(long)的使用class
sleep(long)与join(long)的区别就在与这里两个方法对于同步的不一样处理上。join方法内部是由wait方法实现,因此在执行完join(long)方法后,当前线程会释放锁,而Thread.sleep(long)则不会释放锁。原理