У меня есть два класса.Синхронизация Java и видимость памяти. Является ли 10 видимым для других потоков?
Один класс - это просто контейнер для целочисленного значения с использованием методов get и set synchronized.
public class Sync {
private int dataSync;
public synchronized int getDataSync() {
return dataSync;
}
public synchronized void setDataSync(int data) {
dataSync = data;
}
}
Другие классы аналогичны. Это просто контейнер для целочисленного значения с методами get и set без синхронизации.
public class NotSync {
private int dataNotSync;
public int getDataNotSync() {
return dataNotSync;
}
public void setDataNotSync(int data) {
dataNotSync = data;
}
}
Теперь мой вопрос «является 10 значением гарантированно видимой для всех других потоков» в конце методы выполнения.
public class RunSync {
public static void main(String[] args) {
RunSync rs = new RunSync();
rs.run();
}
private NotSync dataNS;
private Sync dataS;
private int data;
public RunSync() {
dataS = new Sync();
dataNS = new NotSync();
}
public synchronized void run() {
data = 100;
dataS.setDataSync(45);
dataNS.setDataNotSync(10);
//Question A: is 10 value guaranteed to be visible to all other
//threads when method exits?
//we are inside a synchronized block aren't we?
//so all writes must be flushed to main memory
}
}
EDIT: Представьте себе, есть другие темы. Это просто быстрый письменный пример. Вопрос идет о том, что точно гарантировано, что он покраснел в основную память, когда заканчивается блок синхронизации.
EDIT2: В соответствии с моделью памяти java «изменения в полях, сделанных одним потоком, гарантированы для того, чтобы быть видимыми для других потоков только при некоторых условиях. Одно условие: записывающий поток освобождает синхронизацию, и поток считывания впоследствии приобретает . тот же синхронизирующий замок
Так что, если другой поток получает блокировку RunSync, он будет гарантированно увидеть 10 в NotSync экземпляре RunSync Даже если NotSync не защищен
EDIT3:? родственный вопрос без окончательного ответа Я все еще ищу. What is the scope of memory flushed or published to various threads when using volatile and synchronized?
EDIT4: Для упрощения примера, что об этом методе из RunSync класса
public synchronized void run2() {
dataNS.setDataNotSync(10);
}
Когда RUN2 выходов, ничего не гарантировано промывать в основную память? Определенный ответ на это ответит на мой вопрос. Если Нет, это означает, что только члены блокировки гарантированно будут сброшены назад и будут видны другим потокам, если другие потоки получат тот же самый замок в RunSync. Ответ - нет гарантии.
EDIT5: и в этом случае утверждается, что это правда?
public class RunSync {
public volatile boolean was10Written = false;
public synchronized void run2() {
dataNS.setDataNotSync(10);
was10Written = true;
}
public void insideAnotherThread() {
if(was10Written) {
int value = dataNS.getDataNotSync();
assert value == 10;
}
}
}
Почему ваш вопрос риторический? –
Это видно другим темам, которые синхронизируются на чем-то перед чтением. –
@Matt Timmermans риторический, потому что это всего лишь пример. Что именно сбрасывается в основную память при синхронизации выходов? только члены замка? Не их содержание? – Mordan