2009-06-02 2 views
2

Я знаю, может быть, ответ на вопрос очевиден. Но если кто-нибудь может дать мне окончательный ответ, это будет полезно.Вопрос о модели памяти Java

Вопрос в том, может ли пакет nava java обеспечить некоторую гарантию согласованности памяти?

Сценарий:

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] 

ли модификация сделана нить А видна нить B, если нет каких-либо синхронизации/безопасно ссылаться на pulication между резьбой A и B резьбы приложением.

Большое спасибо за помощь.

ответ

5

Мое предположение заключается в том, что запрос TCP не дает никаких официальных гарантий относительно синхронизации потоков.

Сказанное, я думаю, что есть простое решение проблемы, которую вы поднимаете: разумно предположить, что запрос TCP по крайней мере столь же дорогостоящий (perofrmance-wise) как приобретение блокировки. Таким образом, вы можете заключить отправку/получение в синхронизированном блоке без существенного снижения производительности. Это гарантирует, что поток B увидит объект X после его изменения.

5

JMM категорически не дает никаких гарантий относительно этого сценария. Если два потока не синхронизируют на том же объекте, между двумя потоками нет гарантии «произойдет раньше». Поэтому, хотя вы можете продемонстрировать изменения X в A, на самом деле произойдет до чтения X в B в хронологическом порядке, нет гарантии, что B будет см. сделанные изменения Отсутствует синхронизация на том же объекте.

Кэширование CPU вступает в игру здесь; B может очень хорошо видеть устаревшие значения в X, потому что кеши не были записаны обратно в основную память (пока).

Вы можете работать с некоторыми конфигурациями оборудования и иногда изредка терпеть неудачу на других. Системы SMP со свободными моделями памяти, скорее всего, потерпят неудачу (думаю, DEC Alpha).

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, вам необходимо выполнить определенную работу, чтобы убедиться, что вы не получите тупик. Например, убедитесь, что вы можете удалить блокировку перед вызовом других объектов.

Смежные вопросы