我正在学习Java的易失性,我的代码是这样的。
public class Test {
public static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
while(flag){
// System.out.println(flag);
}
System.out.println("end");
});
t1.start();
Thread.sleep(100);
Thread t2 = new Thread(()->{
flag = false;
System.out.println("changed");
});
t2.start();
}
}
我知道如果flag没有volatile,线程就不会存在。这是能见度的问题。
但是,如果我在while循环中编写一些代码,如System.out.println("abc")
,t1线程将读取新值并停止循环。
我知道如何使用volatile来解决可见性问题,所以我的问题是:
为什么当我写System.out时,t1可以读取标志的新值。while循环中的println(“abc”)
?
当您这样做时:
while(flag){
// System.out.println(flag);
}
您将具有空体的循环,这可能导致在场上旋转所知道的;从源头可以读到:
在空循环语句的条件下重复读取非易失性字段可能会导致无限循环,因为编译器优化可能会将此字段访问移出循环。
但是,通过添加语句< code > system . out . println(flag);在你的循环中,你要避开旋转磁场。尽管如此,如果线程< code>t1从其高速缓存中读取值为< code>true的字段< code>flag,则该线程将仅在存储该字段值的高速缓存行无效时停止,并且该线程从主存储器中获得新的更新值< code>flag字段(即< code>flag=false)。
除其他事项外,易失性
可确保线程将读取标志
字段的最大更新值。因此,使字段标志
可变
可确保:
while(flag){
// System.out.println(flag);
}
潜在的编译器优化不会将对字段标志
的访问移出循环。
但是,如果我在 while 循环中编写一些代码,如 System.out.println(“abc”),则线程 t1 将读取新值并停止循环。
这是双重的:首先,通过添加< code > System.out.println(" ABC ")您将避免自旋场问题;其次,如果查看system . out . println代码:
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
您可以看到有一个synchronized
被调用,这将增加线程不是从缓存而是从主内存读取字段标志
的可能性。
问题内容: 如果从多个线程访问Java中的变量,则必须确保安全发布它们。这通常意味着使用或。 我的印象是,我的一些同事没有认真对待这个问题,因为他们“从未听说过,他们的程序已经工作了很多年”。 所以我的问题是: 有人可以提供一个示例Java程序/片段来可靠地显示数据可见性问题。 我认为运行程序并看到意外的NPE或过时的变量值会比理论上的解释更有帮助,这是无法证明的。 非常感谢你的帮助! 更新: 只
问题内容: 当我阅读“ 实践中的Java并发性 ” c03时,我对以下程序感到困惑: 由于重新排序和线程可见性,循环可能永远不会停止,或者输出可能为零,但是我已经尝试了很多次,并且输出始终为42。所有原因是我太幸运了吗? 问题答案: 所有的原因是我太幸运了吗? 不必要。这也将取决于您的处理器体系结构和JVM实现。那就是微妙的内存模型问题的问题之一:它们很难在野外复制。
如何从多个线程同时访问静态变量。 如果我有这样的课 我需要访问线程1的值,比如 从线程2中,我需要设置如下值 这会导致内存冲突吗?。如果是,建议使用什么方法来处理这种情况?。
1):单线程应用程序只会在用户的CPU上使用1个线程吗?提供更多的线程会使用多个CPU内核吗?如果声明的线程比用户的CPU多,会发生什么?
本文向大家介绍浅析Python多线程下的变量问题,包括了浅析Python多线程下的变量问题的使用技巧和注意事项,需要的朋友参考一下 在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁。 但是局部变量也有问题,就是在函数调用的时候,传递起来很麻烦: 每个函数一层一层调用都这么传参数那还得了?用
如图所示, 位置 2 和位置3 为什么可以访问 位置1 (也就是主线程)的 point 局部变量 ? 毕竟 位置 2 和位置3 是另外两个线程啊 !! 当我加上 第10行代码后,thread1 和 thead2 中都不能访问主线程中的point 了。我知道这是内部类的“事实最终变量” 的限制。 如下图所示,就是我不理解的地方。(在 “栈内存” 层面) 我的猜测:之所以 thread1 和 trea