调用者阻塞,直到getFoo()准备好了值? [英] Callers block until getFoo() has a value ready?
问题描述
我有一个Java Thread
,它暴露了其他线程想要访问的属性:
I have a Java Thread
which exposes a property which other threads want to access:
class MyThread extends Thread {
private Foo foo;
...
Foo getFoo() {
return foo;
}
...
public void run() {
...
foo = makeTheFoo();
...
}
}
问题在于从运行到 foo
可用时间很短。呼叫者可以在此之前调用 getFoo()
并获得 null
。我宁愿他们只是阻塞,等待,并在初始化发生后获取值。 ( foo
之后永远不会改变。)在它准备好之前它将是几毫秒,所以我对这种方法很满意。
The problem is that it takes some short time from the time this runs until foo
is available. Callers may call getFoo()
before this and get a null
. I'd rather they simply block, wait, and get the value once initialization has occurred. (foo
is never changed afterwards.) It will be a matter of milliseconds until it's ready, so I'm comfortable with this approach.
现在,我可以用 wait()
和 notifyAll()
来实现这一点,并且有一个95%的几率我会做对的。但我想知道你们都会怎么做;在 java.util.concurrent
中有一个原语可以做到这一点,我错过了吗?
Now, I can make this happen with wait()
and notifyAll()
and there's a 95% chance I'll do it right. But I'm wondering how you all would do it; is there a primitive in java.util.concurrent
that would do this, that I've missed?
或者,你会如何构建它?是的,make foo
volatile。是的,在内部锁定对象
上同步,并在循环时将支票放入,直到它不是
空
。我错过了什么吗?
Or, how would you structure it? Yes, make foo
volatile. Yes, synchronize on an internal lock Object
and put the check in a while
loop until it's not null
. Am I missing anything?
推荐答案
如果 foo
仅初始化一次, CountDownLatch
非常合适。
If foo
is initialized only one time, a CountDownLatch
is a great fit.
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();
}
}
锁存提供与 volatile
关键字,意味着读取线程将看到线程分配的 foo
的值,即使 foo
未声明 volatile
。
Latches provide the same visibility behavior as the volatile
keyword, meaning that reading threads will see the value of foo
assigned by the thread, even though foo
isn't declared volatile
.
这篇关于调用者阻塞,直到getFoo()准备好了值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!