第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

這一次,帶你徹底搞懂join的用法

標(biāo)簽:
Java

java多线程里的join,从字面意思来看是联合,合并的意思,但如果面试时这么回答,基本上可以断定面试者还没搞懂。
join究竟能干什么,今天给出一个最通俗的解释,那就是
在多线程环境下实现暂时以单线程执行,或者说在并行执行的环境中实现暂时以串行执行。
为了说明这个问题,我们看一段再常见不过的代码,代码内容是,让三个线程分布去打印一段内容

//代码块1
public class TestJoin {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new DoSth());
        Thread t2 = new Thread(new DoSth());
        Thread t3 = new Thread(new DoSth());
        t1.start();
        t2.start();
        t3.start();
        System.out.println("主线程执行");
    }
}

class DoSth implements Runnable {
    @Override
    public void run() {
        int n = 5;
        while (n > 0) {
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            n--;
        }
    }
}

执行结果如下:

线程1执行
线程2执行
线程3执行
线程2执行
线程3执行
线程1执行
线程2执行
线程3执行
线程2执行
线程3执行
线程2执行
线程3执行
线程1执行
线程1执行
线程1执行

可见三个线程各自并行执行,并无明确的先后顺序。
但如果我们在t.start()后面加上这行代码,

//代码块2
t1.start();
t1.join();

看会出现看什么样的结果:

线程1执行
线程1执行
线程1执行
线程1执行
线程1执行
线程2执行
线程3执行
线程3执行
线程2执行
线程3执行
线程2执行
线程3执行
线程2执行
线程3执行
线程2执行

可以看到线程1执行结束之后线程2和3才开始执行,可见在线程1执行过程中,其他线程并未执行,线程1结束后,线程2,线程3开始并行执行,这就印证了前面的结论,即:join的作用是在多线程环境下暂时以单线程执行。
明白了这一点,接下来的问题是,这个特性是怎么实现的呢?
我们跟到源码:可以看到
//代码块3
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;
    }
}

}

在第12行调用了wait,注意这里的wait,它并不是指线程线程1对象执行wait,而是线程1的调用者,也就是相当于在主线程去执行wait,
可等价理解为以下伪代码:

t1.start();
while(t1.isAlive()){
    Thread.currentThread().doWait()
}

此时执行流程会在代码块3的11-13行循环执行,当线程1执行完毕时,其生命周期结束,isAlive()返回false,11-13行退出循环,继续执行下面的代码,此时又切换为并行执行状态。
对于以上执行效果,我们完全可以不用创建t1线程,而是把在主线程中直接去调用t1的核心逻辑,代码如下:

public static void main(String[] args) throws InterruptedException {
    //Thread t1 = new Thread(new DoSth(), "线程1");
    Thread t2 = new Thread(new DoSth(), "线程2");
    Thread t3 = new Thread(new DoSth(), "线程3");
    //t1.start();
    //t1.join();
    new DoSth().run();//直接调用业务逻辑,而不是分配线程去执行
    t2.start();
    t3.start();
    System.out.println("主线程执行");
}

和之前的代码相比,本来需要在子线程t1中执行的内容,通过在主线程中执行达到了相同的效果,而这种特性,就体现了所谓的join,现在你明白为什么叫join了吧?
join在实际应用当中有什么用呢?
把以上代码改造一下,用一个例子来说明。

public static void main(String[] args) throws InterruptedException {
    Thread t1 = new Thread(new DoSth(), "小组1");
    Thread t2 = new Thread(new DoSth(), "小组2");
    Thread t3 = new Thread(new DoSth(), "小组3");
    t1.start();
    t2.start();
    t3.start();
    t1.join();
    t2.join();
    t3.join();
    System.out.println("集合完毕");
}

执行结果:

小组3正在集合
小组1正在集合
小组2正在集合
小组3正在集合
小组1正在集合
小组2正在集合
小组3正在集合
小组1正在集合
集合完毕

当我们需要多个子线程分布去完成各自的任务,并在这些子线程全部完成后,主线程做统一汇总时,join就派上用场了。
不过细心的读者会发现,这些子线程并未返回任何结果,如果我们需要返回结果供主线程使用时,该怎么实现,针对这一需求,单靠实现Runnable的方式已经无法做到了,此时需要用到另外的接口:Feature和Callable。

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消