Queue接口函数
入队函数
队尾里面添加一个元素,成功返回true,失败就扔异常
boolean add(E e);
//推荐使用该方法
boolean offer(E e);
出队函数
队头移除一个元素,并返回这个元素
//和poll的区别是队列空时会扔异常
E remove();
//队列为空时返回null
E poll();
获取队头函数
返回队头元素,但不会把这个元素从队列里面移除
//队列空时扔异常
E element();
//队列空时返回null
E peek();
ArrayBlockingQueue实现
数组实现,循环下标。创建时要求传入数组容量。
入队出队时一把锁锁住整个数组,即入队和出队互斥。
入队额外提供put函数,相比较offer。队列满时,offer会直接返回false,put则会阻塞入队线程。
入队时当队列已满,入队线程会阻塞(put),队列不满时正常入队,入队成功后会唤醒阻塞的出队线程。
出队提供额外的take函数,相比较poll函数。队列空时poll返回null,take则会阻塞出队线程。
出队时当队列为空,出队线程会阻塞(take),队列不空时正常出队,出队成功后会唤醒阻塞的入队线程。
LinkedBlockingQueue
链表实现,创建时如果不传入容量,默认Integer.MAX_VALUE。
两把锁,一把锁出队take,一把锁入队put。即出队和入队不互斥。
入队时当队列已满,入队线程会阻塞。队列不满时,入队成功会判断队列元素+1是否小于队列容量,是则会尝试唤醒其它阻塞中的入队线程。最后判断队列添加前元素是否是0(刚由空转非空),是则还需要唤醒出队线程。
出队时队列为空,出队线程阻塞。队列不为空,出队成功后判断出队前队列中元素是否大于1,是则唤醒其它出队线程。最后判断出队前队列中元素个数是否等于队列容量,是则还需要唤醒入队队列。
PriorityBlockingQueue
元素需要实现排序(Comparable接口)
底层采用数组实现的二叉堆,元素小的优先出队
会自动扩容
其它和ArrayBlockingQueue差不多
DelayQueue
延迟的PriorityBlockingQueue
按过期时间由小到大排序,取出队头时判断有没有过期,过期则返回元素,没过期则线程阻塞x(过期时间)后重新出队。
LinkedBlockingDQueue
LinkedBlockQueue是单向链表,LinkedBlockingDQueue是双向链表。其它基本差不多。
CopyOnWriteArrayList
类似于乐观锁,先查后写。除了写相关函数,其它和ArrayList差不多。
add函数锁住整个add操作,add前先copy一份原数据,add操作在新copy的这份数据里面操作,操作结束后用新数据覆盖原数据。remove也是相同的操作。
CopyOnWriteArraySet
封装的CopyOnWriteArrayList,保证了内部元素不重复。
ConurrentLinkedQueue/DQueue
链表实现方式,采用cas的方式保证并发
ConcurrentSkipListMap/Set
采用跳表实现的有序key的并发map
SynchronousQueue
本身没有容量,先调put时,put线程会阻塞,直到调用take时,两个线程才同时解锁。同理,3个put需要3个take才能解锁。
公平采用TransferQueue实现,非公平采用TransferStack实现