Есть кое-что, что мешает мне с моделью памяти Java (если я даже все правильно понимаю). Если есть два потока A и B, нет никаких гарантий, что B когда-либо увидит значение, записанное A, если только A и B не синхронизируются на одном мониторе.
Для любой архитектуры системы, которая гарантирует когерентность кэша между потоками, проблем нет. Но если архитектура не поддерживает аппаратную когерентность кэша, это, по сути, означает, что всякий раз, когда поток входит в монитор, все изменения памяти, сделанные до этого, должны быть зафиксированы в основной памяти, а кэш должен быть аннулирован. И это должен быть весь кэш данных, а не просто несколько строк, поскольку у монитора нет информации о том, какие переменные в памяти он защищает.
Но это, безусловно, повлияет на производительность любого приложения, которое необходимо часто синхронизировать (особенно такие вещи, как очереди заданий с короткими работами). Так может ли Java работать достаточно хорошо на архитектурах без аппаратной когерентности кеша? Если нет, то почему модель памяти не дает более надежных гарантий видимости? Разве не было бы более эффективно, если бы для языка требовалась информация, которую охраняет монитор?
На мой взгляд, модель памяти дает нам худшее из обоих миров, абсолютная необходимость синхронизации, даже если согласованность кэша гарантирована аппаратно, а с другой стороны, плохая производительность на несогласованных архитектурах (полное очищение кэша). Так что, не должно ли он быть более строгим (требовать информацию, охраняемую монитором) или более потерять и ограничить потенциальные платформы для согласованных с кэшем архитектур?
Как сейчас, это не имеет особого смысла для меня. Может кто-нибудь выяснить, почему эта конкретная модель памяти была выбрана?
РЕДАКТИРОВАТЬ: мое использование строгого и проигрышного было плохим выбором в ретроспективе. Я использовал «строгий» для случая, когда меньше гарантий и «проиграл» для противоположного. Чтобы избежать путаницы, лучше говорить о более сильных или более слабых гарантиях.