在启动时控制竞争条件

Wil*_*ung 3 java concurrency

我有一些代码,我想要进行一次初始化.但是这段代码没有明确的生命周期,所以在我的初始化完成之前,我的逻辑可能被多个线程调用.所以,我基本上要确保我的逻辑代码"等待"直到初始化完成.

这是我的第一次削减.

public class MyClass {
    private static final AtomicBoolean initialised = new AtomicBoolean(false);

    public void initialise() {
        synchronized(initialised) {
            initStuff();
            initialised.getAndSet(true);
            initialised.notifyAll();
        }
    }

    public void doStuff() {
        synchronized(initialised) {
            if (!initialised.get()) {
                try {
                    initialised.wait();
                } catch (InterruptedException ex) {
                    throw new RuntimeException("Uh oh!", ex);
                }
            }
        }

        doOtherStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)

我基本上想确保这会做我认为它会做的事情 - 阻止doStuff直到initialised为真,并且我没有错过竞争条件,其中doStuff可能会卡在Object.wait()上那将永远不会到来.

编辑:

我无法控制线程.我希望能够控制何时完成所有初始化,这就是doStuff()无法调用initialise()的原因.

我使用了AtomicBoolean,因为它是值持有者和我可以同步的对象的组合.我本可以简单地使用"public static final Object lock = new Object();" 和一个简单的布尔标志.AtomicBoolean方便地给了我两个.无法修改布尔值.

CountDownLatch正是我想要的.我还考虑过使用含有0许可证的Sempahore.但CountDownLatch非常适合这项任务.

eri*_*son 6

这是库和内置并发控件的奇怪组合.像这样的东西更清洁:

public class MyClass {

  private static final CountDownLatch latch = new CountDownLatch(1);

  public void initialise() {
    initStuff();
    latch.countDown();
  }

  public void doStuff() {
    try {
      latch.await();
    } catch (InterruptedException ex) {
      throw new RuntimeException("Uh oh!", ex);
    }
    doOtherStuff();
  }

}
Run Code Online (Sandbox Code Playgroud)