这个对象是否在监听器线程安全中被修改?

时间:2018-08-27 13:31:19

标签: java multithreading memory concurrency volatile

在以下代码段中,假设有两个线程从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];
}

1 个答案:

答案 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);
}