【发布时间】:2023-03-30 18:44:01
【问题描述】:
试图获得 Java 多线程基础知识 我遇到了一个我无法理解的案例。社区,请分享您的经验为什么会这样: 我有一个 Runnable:
class ImproperStateWorker implements Runnable {
private int val = 0;
@Override
public void run() {
//Where are missing ticks?
for (int i = 0; i < 1000; i++) {
val++;
Thread.yield();
val++;
}
showDataState();
}
public void showDataState() {
System.out.print(Thread.currentThread() + " ; ");
System.out.println(val);
}
}
通过以下方式启动:
public class ImproperState {
public static void main(String[] args) {
ImproperStateWorker worker = new ImproperStateWorker();
for (int i = 0; i < 2; i++) {
Thread thread = new Thread(worker);
thread.start();
}
}
}
我知道这个想法是通过使用synchronized() {...} 等使两个增量操作成为原子操作。
但我对以下内容感到困惑:为什么运行这两个 Runnables(不同步)不会产生 4000(每个任务 1000 x 2 增量)的一致结果?不管上下文如何在两个任务之间切换,我希望这些任务每个都执行 2000 个增量,我不在乎顺序是什么。
但是,程序输出大约为 3.5K。
我能想到的唯一想法是出现“缺失”增量,因为其中一些是同时产生的,因此从两个线程调用的val++ 实际上将值增加了 1。但这是一个非常模糊的假设。感谢您分享您的经验。
【问题讨论】:
-
执行回答:是的
-
详细说明,
i++由read、increment、assign步骤组成。有很多重叠的机会。
标签: java multithreading atomic context-switch