繁体   English   中英

Thread.join() 没有原子性

[英]No atomicity with Thread.join()

考虑以下代码:

Thread t1 = new Thread(() -> {
  System.out.println("t1 running");
  System.err.println("foo 1");
});
Thread t2 = new Thread(() -> {
  System.out.println("t2 running");
  System.out.println("foo 2");
});
Thread t3 = new Thread(() -> {
  System.out.println("t3 running");
  System.out.println("foo 3");
});

t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();

上面的所有线程都应该按顺序执行,因为我不是一次全部启动它们,并且我确实在每个线程上调用 Thread.join() 以阻止主线程执行,直到每个线程都被执行。 我期望以下原子 output:

t1 running
foo 1
t2 running
foo 2
t3 running
foo 3

但这是实际结果,这确实让我感到困惑:

t1 running
t2 running
foo 2
t3 running
foo 3
foo 1

就我而言,唯一可能的原因是如果在引擎盖下为System.err创建了另一个线程,打印“foo 1”。 请告诉我这种行为的真正原因是什么。

当然代码是按顺序执行的,你可以检查一下(不是通过检查不同流中的日志顺序:)

    AtomicInteger counter = new AtomicInteger(0);
    Thread t1 = new Thread(() -> {
        System.out.println("t1 running [" + counter.incrementAndGet() + "]");
        System.err.println("foo 1 [" +counter.incrementAndGet() +"]");
    });
    Thread t2 = new Thread(() -> {
        System.out.println("t2 running [" +counter.incrementAndGet() +"]");
        System.out.println("foo 2 [" + counter.incrementAndGet() +"]");
    });
    Thread t3 = new Thread(() -> {
        System.out.println("t3 running [" + counter.incrementAndGet() +"]");
        System.out.println("foo 3 [" + counter.incrementAndGet()+"]");
    });

    t1.start();
    t1.join();
    t2.start();
    t2.join();
    t3.start();
    t3.join();

output:

t1 running [1]
t2 running [3]
foo 2 [4]
t3 running [5]
foo 3 [6]
foo 1 [2]

请注意, outerr流可以以不同方式刷新(在我的情况下,当我在终端中运行此代码时,我看到了正确的预期顺序,但是当我在 IntelliJ 中运行时,我看到了不正确的顺序,请参阅

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM