这个类扩展了 Thread,一旦它被创建,线程就会启动。这是代码:

class Controller extends Thread implements ConfigurationObserver{

    private int refreshMS;

    //...

    @Override
    public void notifyConfiguration(ConfigurationModel config) {
        refreshMS = config.getRefreshMs();
    }

    @Override
    public void run() {
        //...
        while (true) {

            try {
                Thread.sleep(refreshMS);
            } catch (InterruptedException ex) {
                //...
            }
        }
    }
}

它遵循 Observer Pattern 。此类将自己订阅 ConfigurationController,每当任何配置参数发生更改时,notifyConfiguration(...) 都会通过 refresMS 方法通知他。

是什么让我对此有点不安全,是属性 Controller 。配置通过 GUI(线程 #1)更改并影响 ojit_code 类(线程 #2)的属性,该类从该类(线程 #3)的运行线程中读取。

Q1: 这会成为竞争条件吗?
Q2: 如果是这样,解决这个问题的最佳方法是什么?

最佳答案



是的。有点。 run() 方法最终可能会使用过时的 refreshMS 值。



这最大限度地减少了竞争条件:

class Controller extends Thread implements ConfigurationObserver{
    private int refreshMS;
    public synchronized void notifyConfiguration(ConfigurationModel config) {
        refreshMS = config.getRefreshMs();
    }

    public void run() {
        while (true) {
            ...
            synchronized (this) {
                rms = refreshMS;
            }
            Thread.sleep(rms);
            ....
        }
    }
}

如果不在同步块(synchronized block)内进行 sleep 调用,就无法完全消除竞争条件。 (这会导致调用 notifyConfiguration 的线程阻塞一段可能无限的时间。坏主意。)

现在,这一切都很好,但您还应该问问自己,竞争条件是否可能对应用程序的执行产生有害影响。

关于java - 并发竞争条件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10995434/

10-12 18:07