容器
- Conllection
○ List
ArrayList
LinkedList
CopyOnWriteList
Vector
Stack
○ Set
HashSet
LinkedHashSet
TreeSet
CopyOnWriteArraySet
SortedSet
EnumSet
ConcurrentSkipListSet
○ Queue
Deque
□ ArrayDeque
□ BlockingQueue
□ LinkedBlockingQueue
BlockingQueue
□ ArrayBlockingQueue
□ PriorityBlockingQueue
□ LinkedBlockingQueue
□ TransferQueue
□ LinkedTransferQueue
□ SynchronousQueue
ConcurrentLinkedQueue
PriorityQueue
DelayQueue
- Map
○ HashMap
HashMap可以用Collections.synchronizedMap(new HashMap())转换为加锁的HashMap
但是这种加锁会比较重,效率和HashTable的效率差不多
1.7是数组+链表,1.8之后是数组+链表+红黑树
○ LinkedHashMap
○ TreeMap
底层是红黑树
○ ConcurrentHashMap
○ ConcurrentSkipListMap
○ WeakHashMap
○ IdentityHashMap
- 计算机中物理存储结构只有两种
○ Array:数组
○ Linked:链表 - 带有Array表示底层由数组实现
- 带有Linked表示底层由链表实现
- 带有Tree表示内部有自然排序
- 带有Concurrent表示非阻塞的同步容器
- 在Java的util包中,线程安全的只有HashTable和Vector,自带锁,但是现在基本不用
JUC高并发包
JUC包中的容器均为线程安全,底层多半用CAS实现,比如Queue
高并发应该编程多考虑Queue和ConcurrentHashMap,少考虑List和HashMap
1. ConcurrentHashMap
- 加入了分段锁的概念,把数据分段存储
- 多线程访问时,只要读线程和锁住的数据不在一段里,就不会发生锁竞争
- 高并发场景下,读的效率会远高于HashMap,但是并发插入数据不一定
2. ConcurrentSkipListMap
- 高并发有排序的Map,底层由跳表实现
- 跳表会把中间元素作为索引,从下往上,每层的数据越来越少,查询数据时会从顶层筛选往下查找
- 用空间换时间的产物
3. CopyOnWriteList和CopyOnWriteSet
- 写时复制的集合,当需要往里面加元素时,会把里面的东西复制一份出来
- 当需要往里面加元素时,会copy一个新的集合,添加完元素后,再把引用指向copy出来的集合
- 这样做不会影响到读的线程,本质是一个ReadWriteLock,底层是由读写锁实现的
- 写的线程特别少,读的线程特别多时,可以用这个来提高效率
4. BlockingQueue
- 线程池用到的内容,阻塞队列,也是Concurrent原子性操作
- Queue中的方法
○ add:添加元素,失败会抛异常
○ offer:添加元素,成功失败会给返回值,现在一般都用offer
○ peek:取值,但是并不会把元素remove掉
○ poll:取值并且remove掉 - BlockingQueue中添加的方法
○ put:添加元素,如果满了的话会阻塞
○ take:取元素,如果没有会阻塞住
○ 这两个方法主要用来做生产消费者模型
○ 阻塞底层实现用的是park - LinkedBlockingQueue
○ 用链表实现的BlockingQueue
○ 无界队列,可以一直添加到内存溢出,没有长度限制 - ArrayBlockingQueue
○ 用数组实现的BlockingQueue
○ 有长度,而且指定长度后不可变 - DelayQueue
○ 和时间有关的BlockingQueue
○ 可以按照元素要求等待的时间来进行排序,时间越短的越先运行 - PriorityQueue
○ 树结构的BlockingQueue
○ 内部是一个二叉树,按照从小到大的自然顺序来排序 - SynchronousQueue
○ 同步的容量为0的BlockingQueue
○ 只有一个线程需要取东西的时候,另外一个线程才能往里面加东西
○ 用来做线程之间的资源交换 - TransferQueue
○ 传递内容的BlockingQueue
○ 添加了transfer方法
○ transfer表示添加完内容后,需要等待结果
○ 生产者线程生产之后会等待消费者线程来消费,消费完了生产者线程才会离开
○ 可以用来处理付款的过程