Java多线程-Thread.join()

Java多线程-Thread.join()

Thread.join()把制定的线程加入到当前线程,可以将两个交替执行的多线程合并为顺序执行的线程。比如在线程B中调用累线程A的join()方法,直到线程A执行完毕后,才会继续执行线程B;

eg:

线程A代码:

public class A extends Thread{

@Override

        public void run() {

           for (int i =0; i <500 ; i++) {

         System.out.println("A--thread:"+i);

           }

}

}

线程B的代码:

public class Bextends Thread {

@Override

    public void run() {

A a =new A();

a.start();

try {

           a.join();// 调用join方法

            for (int i =0; i <500 ; i++) {

         System.out.println("Thread-B:"+i);

}

}catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args){

new B().start();

}

}

观察结果:在线程B的run方法中启动类线程A的start方法和join(),打印的结果没有交叉执行。可以得出上面的结论。感兴趣的同学可以将线程a.join()方法注视掉,观看打印结果有没有交叉执行。   

结论:   当我们调用某个线程的join这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行

源码解析:

Thread 源码有3个join方法重载。

public final void join()throws InterruptedException {

join(0);

};

public final synchronized void join(long millis,int nanos)

throws InterruptedException {

if (millis <0) {

throw new IllegalArgumentException("timeout value is negative");

}

if (nanos <0 || nanos >999999) {

throw new IllegalArgumentException(

"nanosecond timeout value out of range");

}

if (nanos >=500000 || (nanos !=0 && millis ==0)) {

millis++;

}

join(millis);

}

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. join() 和 join(long millis, int nanos) 最后都调用了 join(long millis)。

b. 带参数的 join() 都是 synchronized method。

c. join() 调用了 join(0),从源码可以看到 join(0) 不断检查当前线程(join() 所属的线程实例,非调用线程)是否是 Active。

d. join() 和 sleep() 一样,都可以被中断(被中断时,会抛出 InterrupptedException 异常);不同的是,join() 内部调用了 wait(),会出让锁,而 sleep() 会一直保持锁。


以本文开头的代码为例,我们分析一下代码逻辑:

B 调用 a.join(),a.join() 再调用 a.join(0) (此时 B 会获得 child 实例作为锁,其他线程可以进入 child.join() ,但不可以进入 child.join(0)(同步的), 因为无法获取锁)。child.join(0) 会不断地检查 child 线程是否是 Active。

如果 child 线程是 Active,则循环调用 child.wait(0)(为了防止 Spurious wakeup, 需要将 wait(0) 放入 for 循环体中;此时 B 会释放 a 实例锁,其他线程可以竞争锁并进入 a.join(0)。我们可以得知,可以有多个线程等待某个线程执行完毕)。

一旦 a 线程不为 Active (状态为 TERMINATED), a.join(0) 会直接返回到 a.join(), a.join() 会直接返回到 B 父线程,B 父线程就可以继续运行下去了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • 进程和线程 进程 所有运行中的任务通常对应一个进程,当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中...
    小徐andorid阅读 2,797评论 3 53
  • 一、认识多任务、多进程、单线程、多线程 要认识多线程就要从操作系统的原理说起。 以前古老的DOS操作系统(V 6....
    GT921阅读 1,006评论 0 3
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,948评论 1 18
  • 说到复制品,我们需要先来看一下,什么复制品? 百度百科给出的解释是这样的: 通过碳纸印相法制出的图像;仿造的物品(...
    苗栋栋阅读 898评论 3 1
  • 隔了窗户纸 说到锁,各种书籍或者博客上嗖嗖嗖就能上来一堆关于锁的名词,比如读写锁、互斥锁、自旋锁,等等。然后介绍这...
    陈半仙儿阅读 187评论 0 0