Если все атрибуты коллекции являются поточно-ориентированными, можем ли мы сказать, что эта коллекция является поточно-ориентированной? - PullRequest
2 голосов
/ 21 декабря 2009

Если все атрибуты (или поля элементов, или элементы данных) коллекции java поточно-безопасны (CopyOnWriteArraySet, ConcurrentHashMap, BlockingQueue, ...), мы можем сказать что эта коллекция потокобезопасна ?

пример:

public class AmIThreadSafe {

    private CopyOnWriteArraySet thradeSafeAttribute;

    public void add(Object o) {
        thradeSafeAttribute.add(o);
    }

    public void clear() {
        thradeSafeAttribute.clear();
    }
}

в этом примере мы можем сказать, что AmIThreadSafe является поточно-ориентированным ?

Ответы [ 4 ]

3 голосов
/ 21 декабря 2009

Предполагая, что под «атрибутами» подразумевается «что содержит коллекция», то нет. То, что Collection содержит поточно-ориентированные элементы, не означает, что реализация Collection реализует add(), clear(), remove() и т. Д. Поточно-ориентированным образом.

2 голосов
/ 22 декабря 2009

Краткий ответ: Нет .

Немного более длинный ответ: поскольку add () и clear () никоим образом не синхронизированы, а HashSet сам по себе не синхронизирован, возможно, что несколько потоков будут в них одновременно.

Редактировать следующий комментарий : Ах. Теперь короткий ответ - Да, Сорта . :)

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

В данном примере, где поддерживаются только add () и clear (), этого не может быть.

Но в более полном классе, где у нас было бы больше интерфейса Collection, представьте вызывающую программу, которой нужно добавить запись в набор, если в наборе уже не более 100 записей.

Этот вызывающий объект хотел бы написать метод примерно так:


void addIfNotOverLimit (AmIThreadSafe set, Object o, int limit) {
   if (set.size() < limit)      // ## thread-safe call 1
      set.add(o);               // ## thread-safe call 2
}

Проблема в том, что, хотя каждый вызов сам по себе является потокобезопасным, два потока могут быть в addIfNotOverLimit (или, в этом отношении, добавление через другой метод вообще), и поэтому потоки A будут вызывать size () и получать 99, а затем вызывать add (), но до того, как это произойдет, он может быть прерван, и поток B мог бы добавить запись, и теперь набор превысил бы свой предел.

Мораль? Сложные операции усложняют определение «потокобезопасности» .

2 голосов
/ 21 декабря 2009

Нет, потому что состояние объекта - это "сумма" всех его атрибутов.

например, вы можете иметь 2 поточно-ориентированные коллекции в качестве атрибутов вашего объекта. Кроме того, ваш объект может зависеть от некоторой корреляции между этими 2 коллекциями (например, если объект находится в 1 коллекции, он находится в другой коллекции, и наоборот). простое использование двух поточно-ориентированных коллекций не гарантирует, что эта корреляция истинна во все моменты времени. вам потребуется дополнительный контроль параллелизма в вашем объекте, чтобы гарантировать, что это ограничение распространяется на 2 коллекции.

, поскольку большинство нетривиальных объектов имеют некоторый тип корреляционных связей между своими атрибутами, использование поточно-ориентированных коллекций в качестве атрибутов недостаточно, чтобы сделать объект потокобезопасным.

1 голос
/ 21 декабря 2009

Что такое безопасность потока?

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

Потокобезопасный объект - это тот, который всегда поддерживает действительное состояние, так как наблюдаемый другими классами и объектами, даже в многопоточной среде.

В соответствии с документацией API, вы должны использовать эту функцию для обеспечения безопасности потока:

synchronizedCollection(Collection c) 
         Returns a synchronized (thread-safe) collection 
         backed by the specified collection

Читая это, я считаю, что вы должны использовать вышеуказанную функцию, чтобы обеспечить потокобезопасную коллекцию. Тем не менее, вам не нужно использовать их для всех коллекций, и есть более быстрые коллекции с поддержкой потоков, такие как ConcurrentHashMap. Базовый характер CopyOnWriteArraySet обеспечивает поточно-ориентированные операции.

...