前言
这里只是简单记录一下,方便自己回顾而已。
正文
join()是在Thread.java中定义
join源码
/** * Waits for this thread to die.[等待这个线程死亡] * @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 void join() throws InterruptedException { join(0); }
最终调用的是 join(long millis)
public final void join(long millis) throws InterruptedException { synchronized(lock) { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } //如果传入0,就走这 if (millis == 0) { //判断是否存活 while (isAlive()) { //0时表示一直等待,直到notifyAll()或notify()通知 lock.wait(0); } } else { while (isAlive()) { //倒计时 long delay = millis - now; if (delay <= 0) { break; } //等待指定的时间 lock.wait(delay); now = System.currentTimeMillis() - base; } } } }
如果传入值millis为0时,需要等待线程死亡(任务结束)才会释放。
如果传入值millis大于0时,要么倒计时结束主动释放,要么线程死亡(任务结束),满足其一即可退出。
demo测试
下面简单的测试一下。先定义一个线程,如下。
private class MyThread extends Thread { public MyThread(String name) { setName(name); } @Override public void run() { super.run(); Log.d(TAG, "name : " + getName() + " start "); for (int i = 0; i < 5; i++) { try { Log.d(TAG, "name : " + getName() + " [ " + i + " ] "); sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } Log.d(TAG, "name : " + getName() + " end "); } }
不使用join()
private void test() { MyThread myThreadA = new MyThread("Thread_A"); myThreadA.start(); Log.d(TAG, "name : " + Thread.currentThread().getName() + " start "); for (int i = 0; i < 5; i++) { Log.d(TAG, "name : " + Thread.currentThread().getName() + " [ " + i + " ] "); try { Thread.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } Log.d(TAG, "name : " + Thread.currentThread().getName() + " end "); }
name : main start name : Thread_A start name : main [ 0 ] name : Thread_A [ 0 ] name : main [ 1 ] name : Thread_A [ 1 ] name : main [ 2 ] name : Thread_A [ 2 ] name : main [ 3 ] name : Thread_A [ 3 ] name : main [ 4 ] name : Thread_A [ 4 ] name : main end name : Thread_A end
main线程和Thread_A一起抢占CPU资源的。
使用join()
下面代码是在上面基础上添加了join()方法,如下:
private void test() { MyThread myThreadA = new MyThread("Thread_A"); myThreadA.start(); //添加join()开始 try { myThreadA.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } //添加join()结束 Log.d(TAG, "name : " + Thread.currentThread().getName() + " start "); for (int i = 0; i < 5; i++) { Log.d(TAG, "name : " + Thread.currentThread().getName() + " [ " + i + " ] "); try { Thread.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } Log.d(TAG, "name : " + Thread.currentThread().getName() + " end "); }
在main()中执行test()方法。执行后打印结果如下:
name : Thread_A start name : Thread_A [ 0 ] name : Thread_A [ 1 ] name : Thread_A [ 2 ] name : Thread_A [ 3 ] name : Thread_A [ 4 ] name : Thread_A end name : main start name : main [ 0 ] name : main [ 1 ] name : main [ 2 ] name : main [ 3 ] name : main [ 4 ] name : main end
上面的打印顺序是有顺序了,都规规矩矩的。也就是CPU一直被Thread_A占用,main老老实实等着Thread_A死亡才可以抢CPU。
小结
调用join()的线程具有优先执行权。
当有线程调用join()后,其他线程会阻塞,直到调用join()线程死亡。
参考文章
《Java并发编程之美》
© 版权声明