为了账号安全,请及时绑定邮箱和手机立即绑定

java多线程 关于join 的问题

java多线程 关于join 的问题

呼啦一阵风 2019-02-19 16:05:09
我想通过join让线程 a b c d顺序打印,但是现在是乱序打印 public class ExJoin extends Thread { Thread thread; public ExJoin(){ } public ExJoin(Thread thread){ this.thread = thread; } @Override public void run() { try { if (thread != null){ thread.join(); } System.out.println(Thread.currentThread().getName()+" is running"); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { Thread threadA = new ExJoin(); threadA.setName("A"); Thread threadB = new ExJoin(threadA); threadB.setName("B"); Thread threadC = new ExJoin(threadB); threadC.setName("C"); Thread threadD = new ExJoin(threadC); threadD.setName("D"); threadC.start(); threadD.start(); threadA.start(); threadB.start(); } }
查看完整描述

3 回答

?
HUX布斯

TA贡献1876条经验 获得超6个赞

按照楼主的代码逻辑,join是无法做到有序的,因为A/B/C/D线程的启动运行依赖于CPU调度,如果线程B未启动线程C调用threadB.join方法是不会生效的。可以看看jdk内置的逻辑实现isAlive()false时直接返回了。

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;
        }
    }
}
查看完整回答
反对 回复 2019-03-01
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

run方法中sleep(1000)确实会顺序出现。我猜测可能是指令重排序,前面的线程已经就绪,但是后面的线程对象还没有创建出来,所以出现了乱序。

查看完整回答
反对 回复 2019-03-01
  • 3 回答
  • 0 关注
  • 465 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信