Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.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_Memory_Model_Io - Fatal编程技术网

Java内存模型问题

Java内存模型问题,java,memory,model,io,Java,Memory,Model,Io,我知道也许这个问题的答案是显而易见的。但如果有人能给我一个明确的答案,那将是很有帮助的 问题是:JavaNIO包能否提供一些内存一致性保证 情况是: Thread A Thread B [modify Object X] [Send a request A over TCP by NIO]

我知道也许这个问题的答案是显而易见的。但如果有人能给我一个明确的答案,那将是很有帮助的

问题是:JavaNIO包能否提供一些内存一致性保证

情况是:

Thread A                                                    Thread B
[modify Object X]                                        
[Send a request A over TCP by NIO]
                                              [receive response for request A over TCP by NIO]
                                              [read Object X]
如果应用程序在线程A和线程B之间没有任何同步/安全的引用脉冲,线程B是否可以看到线程A所做的修改


非常感谢您的帮助。

我猜TCP请求不会对线程同步做出任何正式保证

也就是说,我认为对于您提出的问题有一个简单的解决方案:可以合理地假设TCP请求至少与获取锁一样昂贵(从性能上看)。因此,您可以将发送/接收包含在一个同步块中,而不会造成显著的性能损失。这将确保线程B在对象X被修改后会看到它。

JMM明确地对此场景不作任何保证。除非两个线程在同一对象上同步,否则两个线程之间不存在“before”保证。因此,即使你可以证明A中X的变化实际上发生在按时间顺序读取B中X之前,也不能保证B在同一对象上没有同步的情况下会看到所做的变化

CPU缓存在这里发挥作用;B很可能会在X中看到过时的值,因为缓存还没有写回主内存

您的代码可能在某些硬件配置上工作,而在其他硬件配置上偶尔会出现故障。具有松散内存模型的SMP系统特别容易出现故障(想想DEC Alpha)。

这不是保证

您应该在X上同步以确保完整性。请注意,应避免将实际发送和接收包含在同步块中

Thread A 
synchronize( X ) {                                               Thread B
    [modify Object X]
    [build request A using data from X]
}                                        
[Send a request A over TCP by NIO]

                                          [receive response for request A over TCP by NIO]
                                              [read Object X] // assuming from a synchronized database or collection.

                                          synchronize( x ) { 
                                              [handle the response]
                                          }
                                          [call methods in other objects]
如果要在线程B中处理响应,请使用X中的状态确保可以处理该消息

如果您需要调用系统的其他部分,这些部分也使用这样的锁,并且可以在X中调用方法,那么您必须做一些工作以确保不会出现死锁。例如,确保可以在调用其他对象之前解除锁定