此对象是否在侦听器线程安全中修改?

Is this object modified in listener threadsafe?

在以下代码段中,假设有两个线程 read/write from/to results。当 eventListener 线程写入 results 时,被阻塞的线程是否能够访问最新的结果?如果没有,什么实用程序(volatileAtomicReference)会有帮助?

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] 就可以了。然而,代码可能会被重写得更清晰一些。

¹ 即所有来自 countDown() happen before 另一个线程 returns 之前的线程的所有写入来自 await() 调用。


一个稍微更清晰的(恕我直言)版本将使用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);
}