1)并发工具类和并发容器
1. HashMap不是线程安全的,HashTable效率低下,因此考虑使用ConcurrentHashMap
jdk1.7及以前,对hashmap中数组进行分段锁的机制,1600多行实现;jdk1.8采用元素锁,锁的是某个key,这个类的实现有6313行,显然占内存和性能比hashmap差不少。
2. ConcurrentSkipListMap有序Map;ConcurrentSkipListSet有序Set;
思想:SkipList跳表,把链表的中随机值加入索引,然后寻址时,就先对比索引,以空间换时间,效率接近红黑树。
3. ConcurrentLinkedQueue无界非阻塞队列;
相当于LInkedList的并发实现,方法:peek:拿到头元素不移除,poll:拿到头元素后移除
4. CopyOnWriteArrayList和CopyOnWriteArraySet
写的时候进行复制,在副本上写,写的过程中在原容器上读;
在写比较多的情况下,内存占用高,数据一致性弱,只能保证数据的最终一致性,不能保证数据的实时一致性,适合读多写少的情况。
注:多用isEmpty()少用size()==来判断容器是否有值,因为size方法会锁住整个容器
2)阻塞队列
1.常用场景:生产者-消费者模式
2.常用方法:
在队列满时:add抛出异常,offer返回结果布尔值,put一直阻塞直到插入成功,offer超时退出
在队列为空:remove抛出异常,poll返回结果布尔值,take一直阻塞,poll超时退出
检查元素:element抛出异常,peek返回结果布尔值;
3.常用阻塞队列
ArrayBlockingQueue:数组结构组成的有界的阻塞队列
先进先出的访问原则,初始化时必须传大小;take和put的时候用同一把锁;
LinkedBlockingQueue:链表结构组成的有界的阻塞队列
先进先出的访问原则,初始化时可以不传大小;take和put的时候用不同锁;看上去比ArrayBlockingQueue好
PriorityBlockingQueue:支持优先级排序的无界阻塞队列
排序,自然顺序升序排序,类自己实现compareTo()方法,初始化时制定一个Comparator比较器
DelayQueue:使用了优先级队列的无界阻塞队列
支持延时获取,队列里的元素要实现Delay接口,指定多少分钟后执行
SynchronousQueue:不存储元素的阻塞队列
每个put操作要等take才会返回,类似接力,你接了我才走。
LinkedTransferQueue:链表结构组成的无界阻塞队列
生产者put时,当前有消费者take,则生产者直接把元素传给消费者
LInkedBlockingDeque:链表结构组成的双向阻塞队列
可以在队列的两端插入和移除,xxxFirst头部操作,xxxLast尾部操作,工作窃取模式。