为什么调用线程的join方法,等待的是执行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; } } }
我们看到,在join方法中,当前执行线程会循环校验被调用线程对象的isAlive方法来确认被调用线程是否执行完任务,如果没有,则会调用使线程阻塞的wait方法。
分析wait方法源码:wait方法是被native修饰的,说明直接使用其他语言与操作系统交互,停止当前线程,也就是当前正在调用join方法执行的线程。
如果代码如图:
主线程是执行线程,将被阻塞。
在测试下:
public void testNotify() throws InterruptedException{ // 创建任务队列 List<ThreadTask> taskList = new ArrayList<>(); ThreadTask task = new ThreadTask(-1); Thread t1 = new Thread(task); Thread t2 = new Thread(new Runnable() { @Override public void run() { Thread t2 = Thread.currentThread(); try { System.out.println("当前线程" + t2.getName()); t2.join();// 主线程调用线程t的join方法,被阻塞的是主线程 } catch (InterruptedException e) { } System.out.println("当前线程" + t2.getName() + "任务结束"); } }); t1.start(); t1.join(); System.out.println("T1结束"); t2.start(); t2.join(); System.out.println("主线程"); task.notifyAll(); }
执行结果:
程序进入了锁死状态。t2线程中执行了t2.join使得t2线程进入阻塞状态,也就是t2线程永远不肯能结束,而在主线程又调用了t2.join,主线程也锁死。