1、join()方法的作用是使线程串行化,比如在线程A中调用线程B的join方法,则线程A执行完后线程B再执行,注意一定要放在一个线程开启之后
public void joinTest1(){ Thread r1 = new Thread(new X(),"A"); Thread r2 = new Thread(new X(),"B"); r1.start(); try { r1.join(); } catch (InterruptedException e) { e.printStackTrace(); } r2.start(); }
class X implements Runnable{ @Override public void run() { for(int i=0;i<10;i++){ try{ TimeUnit.SECONDS.sleep(1); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":"+i); } } }
上面的方法会让主线程(joinTest1)阻塞,待r1执行完后再执行r2线程,因为r2的开启是在主线程中执行的
2、join(long millis)方法是让线程等待 millis毫秒后再和主线程并行操作
有参数的join是把该线程放入到最先执行的位置一段时间,
如果超过这个时间,该线程依然恢复到并行执行
注意:
1、jdk规定join(0)指的是无限等待即join(0)<==>join()
2、join方法必须在start方法之后执行
public void joinTest2(){ Thread r1 = new Thread(new X(),"A"); Thread r2 = new Thread(new X(),"B"); r1.start(); try { r1.join(2000); } catch (InterruptedException e) { e.printStackTrace(); } r2.start(); }
上面代码可以看到r1线程执行了2000毫秒后r1和r2重新并行执行
3、join的底层原理
其源码如下:
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; } } }可以看到当在线程A中调用线程B份join方法时,会使线程A调用自己的wait方法从而进行阻塞线程A,以达到让线程B执行的目的