Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从EDT传递数据:是否需要volatile?_Java_Thread Safety - Fatal编程技术网

Java 从EDT传递数据:是否需要volatile?

Java 从EDT传递数据:是否需要volatile?,java,thread-safety,Java,Thread Safety,我有一个后台线程,它在start变量变为true之前不会开始处理: class MyBackgroundThread implements Runnable { // ... public void run() { while(true) { if(!start) continue; doSomethingWith(myValue); } } } 通过单击JFrame上的按钮,可以将st

我有一个后台线程,它在
start
变量变为
true
之前不会开始处理:

class MyBackgroundThread implements Runnable {
    // ...

    public void run() {
        while(true) {
            if(!start) continue;

            doSomethingWith(myValue);
        }
    }
}

通过单击
JFrame
上的按钮,可以将
start
变量设置为true,当然,JFrame在事件调度线程上运行。后台线程类中还有一个
myValue
字段,可通过单击按钮进行设置:

startBtn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        backgroundThreadInstance.setMyValue(100);
        backgroundThreadInstance.setStart(true);

        // ...
    }
});

如您所见,在将
start
设置为
true
之前,它会为
myValue
赋值。这是否意味着不需要将
myValue
start
设置为
volatile
?由于
myValue
是先写入的,因此它将在
start
之前泄漏到后台线程,因此后台线程永远不会有机会处理未初始化的
myValue

简短回答是肯定的。虽然,在实践中,你的线程可能最终会看到变为true的情况,但理论上它可能永远不会发生

但是,同意@NamshubWriter的观点,有比忙/闲循环更好的方法来实现这一点。我喜欢他的建议,设置整数,然后将其提交给ExecutorService。e、 g

public void actionPerformed(ActionEvent e) {
  BackgroundRunnableInstance runnable = new BackgroundRunnableInstance();
  runnable.setMyValue(100);  // could be in the constructor instead
  someExecutorService.submit(runnable);
}

一个区别是,如果他们多次按下按钮,就会启动多个Runnable。这可能是您想要的,也可能不是您想要的。

与其在
MyBackgroundThread
中进行您自己的旋转循环,为什么不使用
CountDownLatch
?更好的是,为什么不创建一个实现
Runnable
的类,并在
actionPerformed()
中创建一个构造函数,该构造函数接受一个整数并将其传递给
ExecutorService
start
变量仍然在两个线程之间共享:
EDT
MyBackgroundThread
。因此,为了确保
EDT
start
的更改值确实反映在
mybackgroundthread
中,您应该在声明
start
变量时使用
volatile
关键字。