在以下代码段中,假设有两个线程从results
进行读取/写入。当eventListener
线程写入results
时,被阻塞的线程能够访问最新结果吗?如果没有,什么实用程序(volatile
,AtomicReference
)会有所帮助?
private Object doStuff() {
CountDownLatch latch = new CountDownLatch( 1 );
Object[] results = new Object[1];
EventObjectListener eventListener = ( String topic, Object eventObject ) -> {
results[0] = eventObject;
latch.countDown();
};
eventReceiver.addEventListener( eventListener );
doThingThatGeneratesEvent();
int waitMagnitude = 10;
TimeUnit waitUnit = TimeUnit.SECONDS;
try {
latch.await( waitMagnitude, waitUnit );
} catch ( InterruptedException e ) {
return null;
} finally {
eventReceiver.removeEventListener( eventListener );
}
return results[0];
}
答案 0 :(得分:2)
是的,CountDownLatch
保证可见度¹,因此,如果await
没有超时,results[0]
就可以了。但是,可以将代码重写得更清楚一些。
¹,即所有线程在countDown()
happen before之前从线程进行写操作,另一个线程从await()
调用返回。
一个稍更清晰的版本(IMHO)将使用CompletableFuture
,如下所示:
CompletableFuture<Object> future = new CompletableFuture();
EventObjectListener eventListener = (topic, eventObject) ->
future.complete(eventObject);
try {
return future.get(waitMagnitude, waitUnit);
} catch(Exception e) {
return null;
} finally {
eventReceiver.removeEventListener(eventListener);
}