线程之间的共享内存不更新

时间:2014-01-01 21:23:32

标签: java multithreading static volatile

我遇到一个问题,即两个线程正在访问共享变量而无法查看上次更改。

我有一个GUI线程,它有一个文本框,鼠标点击监听器,一旦记录一下,创建一个新的线程,将值注入文本框,当第二次鼠标点击被调用时,最后创建的线程将被停止并且将创建一个新的,也将注入值等等。

public class SomeGuiClass{
    private static boolean isRunning = false;
    private static boolean canRun = true;
    private Thread thread;     

    public SomeGuiClass(){
        txt.addMouseListener(new MouseListener() {
            @Override
            public void mouseDoubleClick(MouseEvent arg0) { 
                if (isRunning){
                    // force the thread to stop running.
                    canRun = false;

                    // waits for the thread to stop his run.
                    while(isRunning);
                }

                thread = new Thread(new Runnable() {
                    @Override
                    public void run() { 
                        SomeGuiClass.isRunning = true;          

                        while(SomeGuiClass.canRun){
                            // Inject values to text box, using Display.asyncExec...

                            Thread.sleep(1000);
                        }

                        SomeGuiClass.isRunning = false;
                    }
                });

                SomeGuiClass.canRun = true;
                thread.start();
            }
        }
    }
}

问题是,读取isRunning的GUI线程无法看到新线程执行的最后一次更新,导致while(isRunning)循环永远在运行。

我尝试使用volatile,同样的事情发生了。看起来我正在做的事情在逻辑上是正确的,只缺乏关于如何丢失java内存模型的技术信息。

1 个答案:

答案 0 :(得分:4)

几点意见:

  • 您必须同时使isRunningcanRun易变,才能使其正常工作

  • 由于您的其他线程每1000毫秒只检查canRun,因此在处理GUI线程上的mouseDoubleClick第二次调用之前,您可能仍有很长的延迟。

  • 让线程忙等待

    通常是一个非常糟糕的主意

    while(true){/*do nothing*/}循环。 你绝对应该使用wait/notify机制来在线程之间进行同步