java 线程 thread.join_java中thread的join方法为什么能让线程插队

在面试中经常会遇到这样的问题:在主线程中有两个子线程,如果能让着两个子线程能顺序的执行?

答案自然是用join来使得两个线程顺序执行,先看一下具体代码

public class ThreadOfJoin {

public static void main(String[] args) throws Exception {

MyThread luck = new MyThread("Luck");

MyThread timi = new MyThread("Timi");

luck.start();

luck.join();

timi.start();

}

@Data

static class MyThread extends Thread {

private String userName;

public MyThread(String userName) {

this.userName = userName;

}

@Override

public void run() {

try {

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

System.out.println(userName + " - " + i);

Thread.sleep(1000);

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

每个线程启动后,打印五次信息,通过不同的名字来区分是哪个线程打印的。执行结果如下

Luck - 0

Luck - 1

Luck - 2

Luck - 3

Luck - 4

Timi - 0

Timi - 1

Timi - 2

Timi - 3

Timi - 4

通过结果可以看到join可以使得两个线程是顺序执行,那为什么join能控制线程顺序执行呢,我们看下join的具体实现

//外部调用的方法

public final void join() throws InterruptedException {

join(0);

}

//内部的具体实现

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通过synchronized关键字来保证线程安全,主线程在调用了luck.start()之后调用了luck.join(),当luck线程未执行完成是,主线程会被以下代码阻塞

if (millis == 0) {//join()方法默认milis为0

while (isAlive()) {//线程未执行完成,此条件为true

wait(0);//等待notify

}

}

当luck线程执行完成之后,此线程的生命周期即将结束,在生命周期结束前,luck线程会使用notifyAll()方法,通知所有正在等待该对象锁的线程(我即将死去,你们不要再等了)。wait(0)接收到notify之后,会再次进行isAlive()判断,luck死亡之后,就跳出循环,join方法结束,之后就继续执行主线程中的其他代码。

同时我们也能看到join方法里面能传递时间参数,大概作用就是等待指定时间之后,如果之前线程还未执行完成,那么久不再等待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值