gpt4 book ai didi

java - 这个多线程代码保证总是返回零吗?

转载 作者:搜寻专家 更新时间:2023-11-01 01:25:38 26 4
gpt4 key购买 nike

我正在拿一本书做一些模拟测试,我发现了这个问题:

import java.util.concurrent.atomic.AtomicInteger;

class AtomicVariableTest {

private static AtomicInteger counter = new AtomicInteger(0);

static class Decrementer extends Thread {

public void run() {
counter.decrementAndGet(); // #1
}
}

static class Incrementer extends Thread {

public void run() {
counter.incrementAndGet(); // #2
}
}

public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Incrementer().start();
new Decrementer().start();
}
System.out.println(counter);
}
}

答案:

This program will always print 0.

但我认为不能保证线程在打印计数器值时已经完成。

我的意思是,大多数时候它会返回 0,但如果您严格遵守理论,则无法保证这一点。

我说的对吗?

最佳答案

有保证。并且没有保证。没有中间立场。

在这种情况下,保证结果始终为零。这是因为线程未连接 - 甚至可能在打印之前从未真正运行过!

例如,在其他排列中,此代码可能执行的序列是:

counter.decrementAndGet();    // #1
System.out.println(counter); // Main thread
counter.incrementAndGet(); // #2
// (and so on, at some arbitrary point after the print)

在 Java 中(根据 JLS)在 happens-before 关系下处理避免这种不希望的交错/执行。

如果线程加入(到带有打印的线程),那么就会建立一个happens-before——在这种情况下,这意味着线程开始了并完成运行 - 结果将保证为零。

public static void main(String[] args) {
final List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final new Incrementer i = new Incrementer();
threads.add(i);
i.start();
final new Decrementer d = new Decrementer();
threads.add(d);
d.start();
}
for (final Thread t : threads) { t.join(); }
System.out.println(counter);
}

查看许多重复项之一:Wait until child threads completed : Java

这就是为什么您使用 ExecutorServiceExecutorCompletionService 并且从不手动处理线程管理,否则极易出错。

关于java - 这个多线程代码保证总是返回零吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32470149/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com