Efekty pamięci synchronizacji w Javie

JSR-133 FAQ mówi:

Synchronizacja jest jednak czymś więcej niż wzajemnym wykluczeniem. Synchronizacja zapewnia, że ​​pamięć zapisywana przez wątek przed lub podczas synchronizowanego bloku jest widoczna w przewidywalny sposób dla innych wątków, które synchronizują się na tym samym monitorze. Po wyjściu z zsynchronizowanego bloku zwalniamy monitor, co powoduje opróżnienie pamięci podręcznej do pamięci głównej, dzięki czemu zapisy wykonane przez ten wątek mogą być widoczne dla innych wątków. Zanim wejdziemy do zsynchronizowanego bloku, uzyskujemy monitor, który powoduje unieważnienie pamięci podręcznej lokalnego procesora, dzięki czemu zmienne zostaną ponownie załadowane z pamięci głównej. Będziemy wtedy mogli zobaczyć wszystkie zapisy widoczne w poprzedniej wersji.

Pamiętam również, że na współczesnych maszynach Sun VM niezakłócona synchronizacja jest tania. Jestem trochę zdezorientowany tym twierdzeniem. Rozważ kod taki jak:

class Foo {
    int x = 1;
    int y = 1;
    ..
    synchronized (aLock) {
        x = x + 1;
    }
}

Aktualizacje x wymagają synchronizacji, ale czy przejęcie blokady usuwa wartość y także z pamięci podręcznej? Nie wyobrażam sobie, żeby tak było, ponieważ gdyby to było prawdą, techniki takie jak pasowanie na zamek mogą nie pomóc. Alternatywnie, JVM może niezawodnie przeanalizować kod, aby upewnić się, że y nie jest modyfikowany w innym zsynchronizowanym bloku za pomocą tego samego zamka, a zatem nie zrzuca wartości y w pamięci podręcznej przy wchodzeniu do zsynchronizowanego bloku?

questionAnswers(7)

yourAnswerToTheQuestion