SynchronousQueue也是一种阻塞队列,同时也是同步队列。
每一个put操作必须等待一个take操作;每一个take操作必须等待一个put操作。
没有任何内部容量。不允许是null元素。内部实现使用了Transferer。竞争机制支持公平和非公平两种: 非公平竞争模式使用的数据结构是后进先出的栈(TransferStack);公平竞争模式使用先进先出的队列(TransferQueue)。
SynchronousQueue以下方法进行介绍:
Iterator() 永远放回空,里面没有东西。
peek 用于返回null
put 向queue存放一个元素,然后一直等待,直到有另一个线程执行take方法取走。
take 向queue中取一个元素,一直等待,直到有另一个线程执行put方法,存放一个元素,并且removed此元素。
offer 向queue里放一个元素后,立即返回,如果此时没有任何线程取走这个元素,那么方法返回false。如果此时正好又一个线程取走这个元素,那么返回true,无论返回true还是false,元素都不存放在队列中。s
poll 向queue里获取一个元素,并且removed这个元素,并立即返回,如果此时有另一个线程正好存放一个元素,那么返回tue,否则返回false。
offer(2000, TimeUnit.SECONDS) 和 poll(2000, TimeUnit.SECONDS) 只是增加了指定等待的时间。
而不是立即返回。
isEmpty()永远是true。
remainingCapacity() 永远是0。
remove()和removeAll() 永远是false。
这些返回的实现,都是通过调用这个接口:
Object transfer(Object e, boolean timed, long nanos)
它大概分为三个步骤:
1 如果等待队列为空,或者队列中节点的类型和本次操作是一致的,那么将当前操作压入队列等待。
2 如果等待队列中的元素和本次操作是互补的,那么就插入一个“完成”状态的节点,并且让他“匹配”到一个等待节点上。 接着弹出这两个节点,并且使得对应的两个线程继续执行。
3 如果队列(栈) 发现他已经有一个完成的节点,那么通过尝试匹配,帮助他出栈
TransferQueue 的代码实现和TransferStack实现略有不同。