调用者阻塞,直到getFoo()准备好了值?

Sea*_*wen 11 java multithreading synchronization properties blocking

我有一个Java Thread,它暴露了其他线程想要访问的属性:

class MyThread extends Thread {
   private Foo foo;
   ...
   Foo getFoo() {
     return foo;
   }
   ...
   public void run() { 
     ...
     foo = makeTheFoo();
     ...
   }
}
Run Code Online (Sandbox Code Playgroud)

问题是从运行到foo可用时需要很短的时间.呼叫者可以getFoo()在此之前致电并获得null.我宁愿他们只是阻塞,等待,并在初始化发生后获取值.(foo之后永远不会改变.)在它准备好之前它将是几毫秒,所以我对这种方法很满意.

现在,我可以通过这种方式实现这一目标,wait()并且notifyAll()有95%的可能性我会做得对.但我想知道你们都会怎么做; 有没有一个原始人java.util.concurrent会这样做,我错过了?

或者,你会如何构建它?是的,制造foo易变的.是的,在内部锁定上同步Object并将检查放入while循环中,直到它不是null.我错过了什么吗?

eri*_*son 16

如果foo仅初始化一次,CountDownLatch则非常适合.

class MyThread extends Thread {

  private final CountDownLatch latch = new CountDownLatch(1);

  ...

  Foo getFoo() throws InterruptedException
  {
    latch.await(); /* Or use overload with timeout parameter. */
    return foo;
  }

  @Override
  public void run() {
    foo = makeTheFoo()
    latch.countDown();
  }

}
Run Code Online (Sandbox Code Playgroud)

锁存器提供与volatile关键字相同的可见性行为,这意味着读取线程将看到线程foo分配的值,即使foo未声明volatile.