Java内存模型问题

时间:2009-06-02 05:53:36

标签: java memory model io

我知道问题的答案可能很明显。但如果有人能给我一个明确的答案,那将会有所帮助。

问题是:java NIO包是否可以提供一些内存一致性保证?

场景是:

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之间没有任何同步/安全引用脉冲,则线程A对线程A进行的修改是否可见。

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:5)

我的猜测是TCP请求不对线程同步做出任何正式保证。

那就是说,我认为你提出的问题有一个简单的解决方案:假设TCP请求至少与获取锁定一样昂贵(按性价比)是合理的。因此,您可以将发送/接收封装在同步块中,而不会显着降低性能。这将确保线程B在修改后看到对象X.

答案 1 :(得分:5)

JMM 明确对此方案不作任何保证。除非两个线程在同一个对象上同步 ,否则两个线程之间没有“事先发生”保证。因此,即使您可以演示A中X的更改实际发生在B 按时间顺序中读取X之前,也无法保证B 所做的更改是没有同一对象的同步。

CPU缓存在这里发挥作用; B可能很好地看到X中的陈旧值,因为缓存尚未写回主存储器(

您的代码可能适用于某些硬件配置,偶尔也会失败。具有松散内存模型的SMP系统特别容易失败(想想DEC Alpha)。

答案 2 :(得分:1)

没有

不保证。

您应该在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中的方法,你必须做一些工作以确保不会出现死锁。例如,确保在调用其他对象之前可以放弃锁定。