【问题标题】:Shared memory between threads not updating线程之间的共享内存不更新
【发布时间】:2014-01-01 21:23:31
【问题描述】:

我面临一个问题,即两个线程正在访问共享变量而无法查看最后的更改。

我有一个 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 内存模型如何缺失的技术信息。

【问题讨论】:

  • 如果你像我描述的那样使用volatile,它应该永远解决你的gui线程循环问题。请查看我在回答中添加的其他注释,希望对您有用。

标签: java multithreading static volatile


【解决方案1】:

几个观察:

  • 您必须同时使 isRunningcanRun 变为 volatile 才能使其工作

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

  • 让线程忙等待通常是一个非常糟糕的主意

    while(true){/*do nothing*/} 循环。 您绝对应该使用wait/notify 机制来代替线程之间的同步

【讨论】:

  • 您的解决方案似乎有道理,我会试一试。但我想知道为什么我的标志只在下次运行时更新..
  • @Matan 你说的是isRunning 还是canRun?请先将它们设为 volatile,然后重试。
  • 成功了。问题是它们都必须标记为 volatile
猜你喜欢
  • 2016-03-01
  • 2012-07-06
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2017-11-30
  • 2019-06-02
  • 2011-12-16
  • 1970-01-01
相关资源
最近更新 更多