在下面的代码片段中,假设两个线程从/向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];
}
是的,CountDownLatch
保证可见性¹,所以如果await
没有超时,results[0]
就可以了。但是,代码可能会被重写以使其更清晰一些。
¹ 即在另一个线程从await()
调用返回之前发生之前countDown()
线程的所有写入。
稍微清晰一点(恕我直言(的版本将使用如下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);
}