Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 此对象是否在侦听器线程安全中修改?_Java_Multithreading_Memory_Concurrency_Volatile - Fatal编程技术网

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

Java 此对象是否在侦听器线程安全中修改?,java,multithreading,memory,concurrency,volatile,Java,Multithreading,Memory,Concurrency,Volatile,在下面的代码段中,假设有两个线程从结果读/写。当eventListener线程写入results时,被阻止的线程是否能够访问最新的结果?如果没有,什么实用程序(volatile,AtomicReference)会有帮助 private Object doStuff() { CountDownLatch latch = new CountDownLatch( 1 ); Object[] results = new Object[1]; EventObjectListen

在下面的代码段中,假设有两个线程从
结果
读/写。当
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];
}

是的,
countdownlock
保证可见性,因此如果
wait
没有超时,
results[0]
就可以了。然而,代码可能会被重写,变得更清晰一些

也就是说,在
countDown()
之前从线程进行的所有写入,另一个线程从
wait()
调用返回


稍微清晰一点的(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);
}
CompletableFuture=newcompletablefuture();
EventObjectListener eventListener=(主题,eventObject)->
future.complete(eventObject);
试一试{
返回future.get(waitmagnity,waitUnit);
}捕获(例外e){
返回null;
}最后{
removeEventListener(eventListener);
}

读取结果[0]是否直接进入内存?你知道JVM获取值的路径吗?@125我不确定你所说的路径是什么意思,但它保证可以通过内存模型工作。请看我的编辑。谢谢你回答了我的问题!如果没有太多问题的话,你能描述一下任何可以使代码更清晰的更改吗?实际上,
countdownlock
在这里很好。但是,您可以通过使用
CompletableFuture
摆脱单一大小的数组,并从侦听器使用结果完成该数组。我将在中编辑它。如果您不需要超时,只需使用
join()
。然后,您不必处理检查过的异常,删除
catch(Exception e){return null;}
将使代码比将任何类型的异常转换为
null
结果更干净。顺便说一下,您还可以使用更简单的lambda语法:
EventObjectListener=(主题,eventObject)->future.complete(eventObject)