thread.join()无原子

发布于 2025-02-12 10:12:45 字数 797 浏览 0 评论 0 原文

考虑以下代码:

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();

上面的所有线程都应该顺序执行,因为我并没有一次启动所有线程,并且我确实在每个启动中启动所有线程,以阻止主线程的执行,直到执行每个主线。 我期望以下原子输出:

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”下。请为我启发这种行为的真正原因。

Consider the following code:

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();

All of the threads above is supposed to execute sequentially since I'm not starting them all at once and I do call Thread.join() on each of them to block the main thread from executing until each has been executed.
I'd expect the following atomic output:

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

But this is the actual result, which does kind of confuse me:

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

As far as I'm concerned the only possible reason for that would be if there was another thread created for System.err under the hood printing "foo 1". Please do enlighten me on what is the real cause for such behaviour.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

呆° 2025-02-19 10:12:45

当然,代码顺序执行,您可以检查此(而不是通过在不同流中检查日志订单!):

    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]

请注意, out er err streams可以被不同地冲洗(就我而言,我在终端运行此代码时会看到正确的预期顺序,但是在Intellij中运行时,我会看到不正确的顺序,请参见这个

of course the code executes sequentially, you can check this(not by checking logs order in different streams!):

    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]

note that the out and err streams can being flushed differently (in my case I see the correct expected order when I run this code in terminal, but I see the incorrect order when I run in IntelliJ, see this)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文