синхронизация Java из модели памяти - PullRequest
2 голосов
/ 23 ноября 2011

Я прочитал, что JVM осуществляет синхронизацию, копируя данные общей переменной из основной памяти в рабочую память потока по этой ссылке.

введите описание ссылки здесь

например, есть такой класс.

class Test {
private Test2 test2 = new Test2();

public void print1() {}

public synchronized void print2() {
    test2.print();
}

}

Если этоТестовый класс выполняется в нескольких потоках, а метод "print2" выполняется в одном потоке, я думаю, что блокировка на Test получена одним потоком, а другие потоки должны ждать, пока блокировка не будет снята.

Теперь у меня есть вопрос.Если Поток получает блокировку Test, означает ли это, что данные Test и Test2 копируются из основной памяти в рабочую память потока?Причина, по которой я говорю, состоит в том, что ключевое слово «synchronized» используется на уровне метода экземпляра, а test2 является переменной экземпляра класса Test.

Я просто пытаюсь уточнить, что копируется из основной памяти в рабочую память потока.

Пожалуйста, исправьте меня, если я ошибаюсь.

Ответы [ 2 ]

2 голосов
/ 23 ноября 2011

Вкратце, все общие переменные будут скопированы (т.е. записаны из кэша в основную память, чтобы все потоки имели одинаковые данные) при использовании синхронизации.Когда вы используете volatile, гарантированно будет скопирована только одна переменная volatile.

Я обнаружил, что это полезный ресурс, затрагивающий тему.

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html


РЕДАКТИРОВАТЬ: Относительно вашего комментария, раздел 17.6 спецификации отвечает на ваш вопрос:

Пусть T будет любой поток, пустьV - любая переменная, и пусть L - любая блокировка.Существуют определенные ограничения на действия, выполняемые T в отношении V и L:

Между действием блокировки T на L и последующим использованием или действием сохранения T для переменной V, действием присваивания или загрузкина V должен вмешаться;более того, если это действие загрузки, то действие чтения, соответствующее этой загрузке, должно следовать за действием блокировки, как видно из основной памяти.( Менее формально: действие блокировки действует так, как если бы оно сбрасывало все переменные из рабочей памяти потока; перед использованием они должны быть назначены или загружены из основной памяти. )

0 голосов
/ 23 ноября 2011

синхронизация требуется только в том случае, если у вас есть хотя бы один поток записи и чтения. Поскольку вы ничего не модифицируете, вам не нужно синхронизироваться.

Единственное, что копируется, это ссылка test2, которая, скорее всего, будет помещена в регистр. Это произойдет независимо от того, синхронизирован ваш метод или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...