从EDT传递数据:是否必要?

时间:2013-02-05 20:25:49

标签: java thread-safety

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

class MyBackgroundThread implements Runnable {
    // ...

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

            doSomethingWith(myValue);
        }
    }
}

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

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

        // ...
    }
});

正如您所看到的,在将myValue设置为start之前,它会为true分配一些内容。这是否意味着不需要将myValuestart设置为volatile?由于myValue被写入第一个,它将在start之前泄露到后台线程,因此后台线程永远不会有机会处理未初始化的myValue

1 个答案:

答案 0 :(得分:1)

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

但是,同意@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);
}

一个区别是,如果他们多次按下按钮,您将启动多个可运行的操作。哪个可能是你想要的,也可能不是。