синхронизируется метод toArray () коллекции? - PullRequest
7 голосов
/ 23 февраля 2012

Если у меня есть подобная синхронизированная коллекция, то

Collection c = Collections.synchronizedCollection(myCollection);

Javadoc для synchronizedCollection упоминает, что внешняя итерация должна быть синхронизирована так:* Могу ли я предположить, что c.toArray() синхронизирован и, следовательно, при выполнении метода не произойдет никаких изменений в коллекции?

Или мне нужно также синхронизировать его:

synchronized (c) {
  c.toArray();
}

Ответы [ 5 ]

5 голосов
/ 23 февраля 2012

Из Javadoc для synchronizedCollection:

Возвращает синхронизированную (поточно-ориентированную) коллекцию, поддерживаемую указанной коллекцией.

Таким образом, c.toArray() не требует дополнительной синхронизации.SynchronizedCollection 'toArray() метод сделает блокировку за вас.По сути, в этом весь смысл synchronizedCollection().

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

2 голосов
/ 23 февраля 2012

Если вы говорите об утилите сбора данных Apache, ответ - да.CollectionUtils.synchronizedCollection(...) возвращает экземпляр SynchronizedCollection, метод toArray() которого:

public Object[] toArray() {
        synchronized (lock) {
            return collection.toArray();
        }
    }
1 голос
/ 23 февраля 2012

Вам это не нужно, метод выполняет синхронизацию за вас.

0 голосов
/ 23 февраля 2012

Кажется, здесь происходит большое заблуждение, что вы можете положиться на фактическую реализацию исходного кода. Это неверно, вы должны полагаться на контракт метода. Поскольку контракт не существует, вы не можете предполагать, что он что-то сделает, в любой момент времени базовая реализация может измениться. Например, посмотрите на следующую функцию:

/**  
*  Returns an empty Collection of Books.
*  
*  
* /  
public Collection returnEmptyBooks()  
{  
    return new HashSet<Book>();
}  

Это означает, что я могу вернуть все, что реализует интерфейс Collection. Подпись плюс документация. Вы не могли бы предположить, что оно синхронизировано или что-то еще в этом роде. Вы также можете сделать вывод, что вы никогда не получите нуль от этого метода, если только контракт не был нарушен.

В случае, если никто не читает комментарии. Любое преобразование из одной структуры данных в другую предполагает итерацию. Вы не можете перейти от List к Set без итерации по всем элементам. То же самое относится и к преобразованию в массив. Вы должны заполнить массив, перебирая исходную структуру данных, поэтому его необходимо синхронизировать.

0 голосов
/ 23 февраля 2012

Если вы используете java.util.Collections, который является частью стандартного API Java Collection, тогда все методы в возвращенной SynchronizedCollection синхронизируются, включая toArray ().См. Блоки кода ниже, взятые из исходного кода Java в java.util.Collections.SynchronizedCollection.

public Object[] toArray() {
   synchronized(mutex) {return c.toArray();}
}

public <T> T[] toArray(T[] a) {
   synchronized(mutex) {return c.toArray(a);}
}
...