JUC包提供了一些并发安全的集合类,用于在多线程环境下进行共享数据的操作,以解决多线程间的竞争条件和线程安全问题。
CopyOnWriteArrayList
相当于线程安全的ArrayList
public class ListTest {
public static void main(String[] arge){
List<String> list = new ArrayList<>();
for (int i=1;i<=10;i++){
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(list);
}).start();
}
}
}
编译报错:ConcurrentModificationException:并发修改异常
解决方案:
1.List<String> list = new Vector<>();
2.List<String> list = Collections.synchronizedList(new ArrayList<>());
3.List<String> list = new CopyOnWriteArrayList<>();
其中Vector和Collections.synchronizedList都是使用synchronized,CopyOnWriteArrayList使用的volatile。
实现了List接口,因此它是一个队列;属于动态数组,在“添加/修改/删除”数据时,都会新建一个数组,并将更新后的数据拷贝到新建的数组中,最后再将该数组赋值给数组。
CopyOnWriteArraySet
它是线程安全的无序的集合,可以将它理解成线程安全的HashSet。
public class ListTest {
public static void main(String[] arge){
//Set<String> set = new HashSet<>();
//在多线程中:编译报错:ConcurrentModificationException:并发修改异常
/**
* 解决方案:
* 1.Set<String> set = Collections.synchronizedSet(new HashSet<>());
* 2.Set<String> set = new CopyOnWriteArraySet<>();
*/
Set<String> set = new CopyOnWriteArraySet<>();
for (int i=1;i<=10;i++){
new Thread(()->{
set.add(UUID.randomUUID().toString().substring(0,5));
System.out.println(set);
}).start();
}
}
}
特点:
1、CopyOnWriteArraySet包含CopyOnWriteArrayList对象,它是通过CopyOnWriteArrayList实现的。而CopyOnWriteArrayList本质是个动态数组队列,所以CopyOnWriteArraySet相当于通过动态数组实现的“集合”;
2、怎么实现不允许重复:CopyOnWriteArrayList额外提供了addIfAbsent()和addAllAbsent()这两个添加元素的API,通过这些API来添加元素时,只有当元素不存在时才执行添加操作!
3、至于CopyOnWriteArraySet的“线程安全”机制,和CopyOnWriteArrayList一样,是通过volatile和互斥锁来实现的。
ConcurrentHashMap
ConcurrentHashMap是线程安全的哈希表,它是通过“锁分段”来实现的
使用:
Map<String,Object> map = new ConcurrentHashMap<>();