哪些Java集合是同步的,哪些不是?
示例:HashSet未同步
答案 0 :(得分:9)
有三组收藏。
Collections.synchronizedXxx()
方法进行同步简而言之,我建议你使用的任何系列都不会同步。
答案 1 :(得分:7)
答案 2 :(得分:7)
简单回答:Collection
的单个实现没有被同步,因为 synchronized
不是类属性,它只适用于方法和块。
我想,你想知道哪些实现是线程安全的,java集合框架中的哪些类可以安全地用在多线程环境中。
信息总是包含在javadoc(like here: Arraylist - 这不是线程安全的)
答案 3 :(得分:6)
线程安全集合-
线程安全,而不必同步整个映射 使用锁定完成写入时非常快的读取 在对象级别没有锁定 使用多个锁。
对象级同步 读取和写入均获得锁定 锁定收藏存在性能缺陷 可能引起争用
向量
哈希表
CopyOnWriteArrayList
CopyOnWriteArraySet
堆栈
所有这些都不是线程安全的
答案 4 :(得分:4)
Collection Interface中的ArrayList,LinkedList,HashSet,LinkedHashset和TreeSet以及HashMap,LinkedHashMap和Treemap都是非同步。
集合界面中的向量是同步
答案 5 :(得分:1)
上一个例子是完全错误的。
首先,您不是从不同的线程访问刚刚同步的列表,您没有证明同步正在正确执行,您无法证明添加进程是原子的。其次,列表本身的synchronized子句是一种不好的做法,您不知道优化器是否会使用列表中的项来进行同步,从而导致意外行为。此外,您正在同步的是访问列表读/写中的元素,而不是列表本身。取出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();
}
}
答案 6 :(得分:0)
同步会降低性能。当然,Java集合不同步。但是Java提供了一个Synchronization Wrappers来同步Java Collection see link
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());
}
}
}
}
答案 7 :(得分:0)
java.util包中的所有集合类(Vector和Hashtable除外)都不是线程安全的。 仅有的两个旧集合是线程安全的:向量和哈希表。为什么? 原因是:同步可能非常昂贵! 您知道,Vector和Hashtable是Java历史悠久的两个集合,它们从一开始就是为线程安全而设计的(如果您有机会查看它们的源代码,您将看到它们的方法都是同步的!)。但是,它们很快暴露出多线程程序中的不良性能。如您所知,同步需要锁定,锁定始终需要花费时间来监视,从而降低了性能。 这就是为什么新集合(列表,集合,地图等)根本不提供并发控制以在单线程应用程序中提供最佳性能的原因。
答案 8 :(得分:0)
import java.util.Collections; //导入此
List<String> syncList = Collections.synchronizedList(new ArrayList<String>());
这是在Java中同步列表的方法。
答案 9 :(得分:0)
线程安全集合
Vector
(父级为 List
)和 Hashtable
(父级为 Map
)synchronized
监视器。 Collections.synchronized
、Collections.synchronizedList()
、Collections.synchronizedSortedMap()
、Collections.synchronizedSet()
...Copy-On-Write(COW)
- 比同步集合具有更好的性能,但具有更大的内存占用。修改数组时会创建新的数组副本(添加、设置、删除)。它是多读操作和后方修改的一个很好的变体。 CopyOnWriteArrayList
, CopyOnWriteArraySet
Compare-And-Swap(CAS)
[About] - ConcurrentLinkedQueue
, ConcurrentSkipListMap
Lock
基于 - ConcurrentHashMap
,BlockingQueue
后代答案 10 :(得分:-3)
我想集合API的每个实现都是用文档编写的。