2015-08-05 1 views
1

Насколько я знаю, «бывает-до» заявляет, что изменения, сделанные внутри синхронизированного, видны для следующего потока, синхронизируясь на одной и той же блокировке.java.io.FileInputStream обращается к частной изменчивой переменной «закрыт» только из внутреннего синхронизированного блока. Зачем?

private final Object closeLock = new Object(); 
private volatile boolean closed = false; 

public void close() throws IOException { 
    synchronized (closeLock) { 
     if (closed) { 
      return; 
     } 
     closed = true; 
    } 
    if (channel != null) { 
     channel.close(); 
    } 

    fd.closeAll(new Closeable() { 
     public void close() throws IOException { 
      close0(); 
     } 
    }); 
} 

Разве это не избыточно?

ответ

2

Синхронизация дает две разные гарантии в Java: видимость и атомарность. Создание переменной volatile гарантирует, что JVM обеспечит видимость записи правильно, следуя «случается раньше», но не гарантирует, что действие check-then-act в синхронизированном блоке является атомарным.

Без гарантии атомарности чередование потоков в этой последовательности if (closed) return; closed = true; может привести к некоторым проблемам синхронизации.

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

+0

Любое воздействие на производительность будет отрицательным, хотя, не так ли? – jaco0646

+0

@ jaco0646 Я предполагал, что я не знаю об усилении или проигрыше производительности при объединении волатильных и синхронизированных блоков для ввода-вывода файлов. Я предполагаю, что этот код был таким образом в течение некоторого времени, не отслеживая историю файла. Поскольку есть способы внести свой вклад в java-кодовую базу, я также предполагаю, что если бы это была большая потеря производительности, она была бы обнаружена и исправлена ​​в какой-то момент. Независимо от того, что результат эффективности выходит за рамки OP. –

1

Эта переменная, скорее всего, доступна для встроенных методов. Вам нужно будет посмотреть исходный код для JDK.

+0

Обеспечивает ли 'volatile' гарантии доступа к собственному методу? – jaco0646

+1

Это хороший вопрос. По-видимому, это не гарантируется (но этот код является частью JDK и, следовательно, может делать конкретные предположения для реализации): http://stackoverflow.com/questions/12130487/jni-java-thread-safe-publishing-sharing-of-effectiveively -immutable-нативной объект –

1

Ключевое слово volatile является избыточным, в соответствии со второй точкой пули Memory Consistency Properties.

разблокировки (синхронизированный блок или метод выход) монитор происходит перед тем, каждым последующим замком (синхронизированный блок или метод запись) из того же монитора. И потому, что происходит, прежде, чем отношения транзитивен, все действия нити до разблокирования произойдет, перед тем все действия проводимого после любого потока блокировки, что монитора.

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