Синхронизированный список Java для цикла - PullRequest
17 голосов
/ 07 сентября 2011

Документация по synchronizedList гласит, что

Обязательно, чтобы пользователь вручную синхронизировал возвращаемый список при его итерации по нему:

List list = Collections.synchronizedList(new ArrayList());
...
synchronized(list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
    foo(i.next());
}

Несоблюдение этого совета может привести к недетерминированному поведению.

Это кажется довольно ясным, но я просто хотел подтвердить, что для каждого цикла запрещено. Например, я не могу сделать что-то вроде следующего, верно?

List<MyType> list = Collections.synchronizedList(new ArrayList(<MyType>));
...
synchronized(list){
    for(MyType m : list){
        foo(m);
        m.doSomething();
    }
}

Ответы [ 4 ]

28 голосов
/ 07 сентября 2011

Да, вы можете - ваш расширенный цикл for в основном такой же, как ваш код, который явно использует итератор.Он сводится к одному и тому же коду - он просто вызывает iterator(), а затем переключается между next() и hasNext() вызовами.

1 голос
/ 28 декабря 2014

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

1 голос
/ 07 сентября 2011

Вы можете сделать это.Цикл foreach компилируется (почти) в тот же байт-код, что и цикл while.Ключи:

  1. Вы синхронизируете блок вокруг цикла, потому что список может меняться во время итерации по нему.
  2. Вы используете список в качестве объекта, на котором вы синхронизируете, поскольку реализация этого класса блокируется на себя (через синхронизированные методы).
0 голосов
/ 07 сентября 2011

Если возможно, вы можете рассмотреть возможность использования неизменяемости, а не синхронизации.

http://docs.guava -libraries.googlecode.com / ГИТ-история / release09 / Javadoc / COM / Google / общие / собирать / ImmutableList.html

...