Какие коллекции Java синхронизированы (потокобезопасны), а какие нет? - PullRequest
16 голосов
/ 18 мая 2011

Какие коллекции Java синхронизированы, а какие нет?

Пример: HashSet не синхронизирован

Ответы [ 10 ]

10 голосов
/ 18 мая 2011

Есть три группы коллекций.

  • Коллекции Java 1.0, которые в основном являются устаревшими классами. Это включает в себя Hashtable, Vector, Stack. Они синхронизированы, но я не рекомендую их использовать. Свойства, возможно, являются одним исключением, но я бы не стал использовать их в многопоточном контексте.
  • Коллекции Java 1.2, добавленные в 1998 году, которые в значительной степени заменили эти коллекции, не синхронизируются, но могут быть синхронизированы с использованием Collections.synchronizedXxx() методов
  • Коллекции параллелизма Java 5.0, добавленные в 2004 году, поддерживают коллекции без блокировок, потокобезопасные.

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

7 голосов
/ 18 мая 2011

Простой ответ: ни одна реализация Collection не синхронизирована , потому что synchronized не является свойством класса, оно применимо только к методам и блокам.

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

Информация всегда включена в javadoc ( как здесь: Arraylist - который не является потокобезопасным)

7 голосов
/ 18 мая 2011

Можно получить синхронизированную версию Java Collection с

Collections.synchronizedCollection(Collection<T> c)

[ javadoc ]

6 голосов
/ 08 декабря 2018

Нитка безопасных коллекций -

  1. ConcurrentHashMap

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

  1. SynchronizedHashMap

Синхронизация на уровне объекта И чтение, и запись получают блокировку Блокировка коллекции имеет недостаток производительности Может вызвать спор

  1. Вектор

  2. HashTable

  3. CopyOnWriteArrayList

  4. CopyOnWriteArraySet

  5. Stack

Все остальные не безопасны для потоков

4 голосов
/ 17 июля 2015

ArrayList, LinkedList, HashSet, LinkedHashset и TreeSet в интерфейсе сбора данных, а также HashMap, LinkedHashMap и Treemap несинхронизированы .

Вектор в интерфейсе коллекции равен Синхронизирован

1 голос
/ 01 августа 2018

Все классы коллекций (кроме Vector и Hashtable) в пакете java.util не являются поточно-ориентированными. Только две устаревшие коллекции являются поточно-ориентированными: Vector и Hashtable. ПОЧЕМУ? Вот причина: синхронизация может быть очень дорогой! Вы знаете, Vector и Hashtable - это две коллекции, которые существуют на ранних этапах истории Java, и они с самого начала созданы для поточной защиты (если у вас будет возможность взглянуть на их исходный код, вы увидите, что все их методы синхронизированы!). Однако они быстро показывают низкую производительность в многопоточных программах. Как вы, возможно, знаете, синхронизация требует блокировок, для мониторинга которых всегда требуется время, что снижает производительность. Вот почему новые коллекции (List, Set, Map и т. Д.) Вообще не предоставляют возможности управления параллелизмом для обеспечения максимальной производительности в однопоточных приложениях.

1 голос
/ 26 апреля 2017

Предыдущий пример совершенно неверен.

Прежде всего, вы не получаете доступ из разных потоков к списку, который вы только что синхронизировали, у вас нет никаких доказательств того, что синхронизация выполняется правильно, вы не можете доказать, чтоПроцесс добавления является атомарным.Во-вторых, предложение о синхронизации по всему списку является плохой практикой, вы не знаете, будет ли оптимизатор использовать элемент в списке для синхронизации, что приведет к неожиданному поведению.Кроме того, вы синхронизируете доступ к элементам в списке для чтения / записи, а не к самому списку.Выньте Collections.synchronized и посмотрите выход.Попробуйте много раз.Пожалуйста, возьмите следующий пример:

class ProcessSomething {
    private List<Integer> integerList = Collections.synchronizedList(new ArrayList<>());
    private void calculate() {
        for (int i = 0; i < 10000; i++) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException ex) {
                Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
            }
            integerList.add(new Random().nextInt(100));
        }
    }
    private void calculate2() {
        for (int i = 0; i < 10000; i++) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException ex) {
                Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
            }
            integerList.add(new Random().nextInt(100));
        }
    }
    public void process() {
        Long start = System.currentTimeMillis();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                calculate();
            }
        });
        t1.start();
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                calculate2();
            }
        });
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(ProcessSomething.class.getName()).log(Level.SEVERE, null, ex);
        }
        Long end = System.currentTimeMillis();
        System.out.println("Duration: " + (end - start));
        System.out.println("List size: " + integerList.size());
    }
}
public class App {
    public static void main(String[] args) {
        new ProcessSomething().process();
    }
}
0 голосов
/ 08 июля 2019

импорт java.util.Collections;// Импортировать это

List<String> syncList = Collections.synchronizedList(new ArrayList<String>());

Вот как вы можете синхронизировать список в Java.

0 голосов
/ 29 марта 2017

синхронизация снижает производительность.Конечно, коллекция Java не синхронизирована.но Java предоставляет обертки синхронизации для синхронизации Java Collection см. ссылку

for example:


    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.List;

    public class SynchronizedListExample {

        public static void main(String[] args) {

            List<String> syncList = Collections.synchronizedList(new ArrayList<String>());

            syncList.add("one");//no need to synchronize here
            syncList.add("two");
            syncList.add("three");
            String st = syncList.get(0); //it is ok here => no need to synchronize

            // when iterating over a synchronized list, we need to synchronize access to the synchronized list
           //because if you don't synchronize here, synchList maybe be changed during iterating over it
            synchronized (syncList) {
                Iterator<String> iterator = syncList.iterator();
                while (iterator.hasNext()) {
                    System.out.println("item: " + iterator.next());
                }
            }

        }

    }
0 голосов
/ 18 мая 2011

Я полагаю, что каждая реализация API коллекции написана в документации.

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