【发布时间】:2021-08-22 04:19:41
【问题描述】:
我是java初学者,第一次使用线程。
class Counter2 {
private int value = 0;
public void increment() {
value++;
printCounter();
}
public void decrement() {
value--;
printCounter();
}
public void printCounter() {
System.out.println(value);
}
}
class MyThread3 extends Thread {
Counter2 sharedCounter;
public MyThread3(Counter2 c) {
this.sharedCounter = c;
}
public void run() {
int i = 0;
while (i <= 100) {
sharedCounter.increment();
sharedCounter.decrement();
try {
sleep((int) (Math.random() * 2));
} catch (InterruptedException e) {
}
// System.out.println(i);
i++;
}
}
}
public class MyTest {
public static void main(String[] args) {
Thread t1, t2;
Counter2 c = new Counter2();
t1 = new MyThread3(c);
t1.start();
t2 = new MyThread3(c);
t2.start();
}
}
这段代码有2个线程和1个Counter,线程之间共享。线程只是重复加 1,减 1 到计数器值。所以,如果我猜,结果应该是 0。因为初始值为 0,并且递增和递减的数量是相同的。但有时最后打印的数字不是0,而是-1或-2等。请解释这是为什么。
【问题讨论】:
-
您的价值不会波动,因此无法保证可见性。进一步的递增和递减运算符是复合赋值运算符的简写,它们不是原子的。如果没有外部同步,您的计数器就不是线程安全的。
-
我已经将这个问题复制到了一个早期的带有计数器和线程的问题,这个问题本质上是相同的问题,但更简单一些。 (细节不同,但问题原因相同,解决方法相同。)
-
我的建议:阅读有关 Java 线程安全的优秀教程。或者更好的是权威的布洛赫教科书(见下文)。这是一个通过反复试验无法弄清楚的话题。
标签: java multithreading counter