Что означает «противоречивая синхронизация»? - PullRequest
7 голосов
/ 15 ноября 2010

Это мой класс Java 1.6:

public class Foo {
  private ArrayList<String> names;
  public void scan() {
    if (names == null) {
      synchronized (this) {
        this.names = new ArrayList<String>();
        // fill the array with data
      }
    }
  }
}

Findbugs говорит:

Inconsistent synchronization of com.XXX.Foo.names; locked 40% of time

Что это значит и что я делаю неправильно?Я пытаюсь избежать проблем, когда два или более клиентов звонят Foo.scan() одновременно.

Ответы [ 2 ]

18 голосов
/ 15 ноября 2010

Это потому что вы синхронизируете только когда вы устанавливаете переменную names, а не когда вы читаете ее. Таким образом, между чтением и записью может выполняться другой поток, и вы создадите два ArrayLists и заполните их данными, первый созданный будет иметь GC'ed.

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

public class Foo {
  private ArrayList<String> names;
    public void scan() {
      synchronized (this)
        if (names == null) {
           this.names = new ArrayList<String>();
           // fill the array with data
         }
       }
     }
  }
7 голосов
/ 15 ноября 2010

Когда вы впервые ссылаетесь на names внутри scan, он находится за пределами блока synchronized.
Например, если scan вызывается дважды из двух разных потоков, а names равно нулю, оно может выглядеть следующим образомэто

  1. if (names == null) из первого потока обрабатывается (до true).
  2. if (names == null) из второго потока обрабатывается (до true).
  3. Первый поток входит в блок synchronized, присваивает names и покидает блок synchronized.
  4. Второй поток входит в блок synchronized, присваивает names и покидает блок synchronized.

Теперь names инициализируется дважды.И это только один из возможных сценариев, когда вы получите неожиданные результаты.

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