java - While 循环并检查静态变量

标签 java multithreading

我有两个线程,在一个线程中我设置静态变量,在另一个线程中我通过这样的函数检查静态变量

Test test= new Test();
while(!Temp.isVarSet()){
}
System.out.println("Variable set");

但是这段代码挂起 - 不会转到 println 语句。但下面的代码可以工作

Test test= new Test();
while(!Temp.isVarSet()){
  System.out.println("I am still here");
}
System.out.println("Variable set");

临时类

public class Temp {

    private volatile static boolean varSet=false;

    public synchronized static void setVarSet() {
        Temp.varSet=true;
    }

    public synchronized static boolean isVarSet() {
        return Temp.varSet;
    }
}

测试类

public class Test{
        public Test() {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    Model model= new Model();
                    View view = new View();
                    Controller controller=new Controller(model, view);
                    Temp.setVarSet();
                  ...
                }
            });
        }
    }

理由是什么?我设置方法 isVarSet() 同步,但没有帮助。
编辑 此代码也有效。

Test test = Test()        
while(!Temp.isVarSet()){
            Thread.sleep(100);
}

最佳答案

您没有发布 TempisVarSet 中发生的情况,但很可能您更改了一个变量。该变量必须标记为 volatile

如果你的类看起来像这样:

public class Temp {
   private static boolean someFlag;

   public static boolean isVarSet() {
      return someFlag;
   }
}

你的循环与示例相同,编译器认为不需要一遍又一遍地读取标志,因为标志在循环内没有改变,并且它优化为不一遍又一遍地读取标志。

someFlag标记为 volatile :

private static volatile boolean someFlag;

将强制运行时在每次迭代时检查标志,而不仅仅是假设该值没有更改。在这种情况下,它会起作用。

来自Oracle docs about atomic access :

Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.

关于java - While 循环并检查静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23457411/

相关文章:

python - 如果我们有 GIL,为什么我们需要线程锁?

java - java中的多线程程序

python - 在垃圾收集中调试 python 段错误

java - JPanel 图像背景与其他 JPanel 重叠

java - PL/SQL 返回 CLOB 和 JDBC 性能

java - 将变量传递给进程

c# - 为单个任务创建多个线程

java - 如何找到存储在同一行mysql的2列中的日期差异

java - NullPointerException ftp.stop() FakeFtpServer/mockFTPServer

c# - 在 silverlight 中使用 while(true) 会很危险吗?