并发容器

类型 并发特性 其他 网页
ConcurrentHashMap CAS synchronzied volatile 保证内存可见性
CopyOnWriteArrayList CopyOnWrite (COW)ReentrantLock控制写独占锁,volatile修饰唯一数据结构数组,依据happen before写对读可见 内存写时,有2个对象,避免GC 存在延迟 https://juejin.im/post/6844903602436374541
ConcurrentLinkedQueue CAS volatile 链表作为其数据结构 tail 和 head 是延迟更新
ThreadLocal 空间换时间 threadLocal 有可能存在内存泄漏 remove 和锁一样(加锁,释放锁),使用后必须remove
BlockingQueue ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue 阻塞
ArrayBlockingQueue 与 LinkedBlockingQueue condition ReentrantLock LinkedBlockingQueue插入和删除采用2个condition,ArrayBlockingQueue只使用一个

ConcurrentLinkedQueue head指针和 tail指针
alt

ThreadLocal 内存泄露

alt
threadLocal外部强引用被置为null 会被GC,但是entry就存在key为null,这样对应的value无法被GC,导致内存泄露。

SimpleDateFormat里面的Calendar操作高并发会出现SET,Clear的问题,Servlet, @Controller, @Service成员变量同样也存在(可以使用@Scope(value = “prototype”)解决)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class ThreadLocalDemo {
private static ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<>();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i &lt; 100; i++) {
executorService.submit(new DateUtil("2019-11-25 09:00:" + i % 60));
}
}

static class DateUtil implements Runnable {
private String date;

public DateUtil(String date) {
this.date = date;
}

@Override
public void run() {
if (sdf.get() == null) {
sdf.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
} else {
try {
Date date = sdf.get().parse(this.date);
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}