java - System.out.println 与 java volatile
问题描述
我有一个这样的例子:
public class MainApp {
private volatile static int MY_INT = 0;
public static void main(String[] args) {
new Thread1().start();
new Thread2().start();
}
static class Thread1 extends Thread {
@Override
public void run() {
while(true) {
MY_INT++;
System.out.println("1 : " + MY_INT);
}
}
}
static class Thread2 extends Thread{
@Override
public void run() {
while(true) {
MY_INT++;
System.out.println("2 : " + MY_INT);
}
}
}
}
输出是:
1 : 1
2 : 2
1 : 3
2 : 4
1 : 5
1 : 7
1 : 8
1 : 9
1 : 10
2 : 6
1 : 11
1 : 13
我不明白为什么在打印 1:10 之后下一行是 2:6。谁能解释一下结果?提前致谢
解决方案
这里有几个问题:
- 线程可能不会并行运行。它们以时间片运行(默认值:PC 上的 15.6 毫秒;每秒 64 个滴答声,请参阅计时器分辨率(Microsoft))。这就是为什么你看不到一个接一个
1:x
,2:x
而是一个接一个1:x
。 - using
volatile
对同步没有帮助。您需要真正的同步对象,例如AtomicInteger
或synchronized
关键字。因此,您可能会看到跳过的数字(输出中不是这种情况,但它可能会发生)。如果您想看到唯一的数字++
,您需要围绕两者进行同步println()
- 控制台输出被缓冲和同步,因为您不希望 2 个
println
语句在一行上混合输出
推荐阅读
- javascript - 如何使用 javascript 在 InDesign 中找到两个 GrepPreference?
- rust - 将 Result 上的迭代器转换为 Result
, _> - html - 角标题错误:角不显示我完整的标题
- mysql - 在MYSQL中基于另外两张表创建一个新表
- android-recyclerview - 更换片段后回收站视图丢失
- azure-data-explorer - 是否有 KQL 查询来限制每个特定类别获得的子结果数量?
- javascript - 如何在 React 中防止过多的 JS 事件处理程序?
- python - 在odoo 12中按项目过滤员工
- html - 从 Angular 材料自动完成打开链接?
- node.js - 为什么 Node 以退出代码 13 退出,而不是挂起?