HashSet
HashSet特点: 元素不可重复,无序,线程不安全,底层是HashMap实现,HashMap的key是唯一不可重复的,value则是用的一个Object对象"占位",主要是key用来存取数据.
案例代码
public class HashSetConcurrentDemo {
public static void main(String[] args) {
Set<String> list = new HashSet();
for (int i = 0; i < 30
; i++) {
new Thread(()->{
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);
},"t"+i).start();
}
}
}
导致原因
高并发情况下,多个线程调用add方法产生的错误.
解决方案
- Collections.synchronizedSet(new HashSet<>())集合工具类
底层是同步代码块synchronized来保证线程安全,其实就是把HashSet方法加了同步代码块,底层操作还是细节没变,就是包装了一层,加上了synchronized修饰保证线程安全
关键代码
- CopyOnWriteArraySet
CopyOnWriteArraySet其实底层是CopyOnWriteArrayList,也是采用ReentrantLock锁来保证线程安全.
每次添加元素都会遍历集合中元素是否存在,存在返回元素所在下标,如果下标大于-1则跳出方法返回false,否则执行添加元素的操作