Queue常用类解析之PriorityQueue
Queue常用类解析之ConcurrentLinkedQueue
Queue常用类解析之BlockingQueue(一):PriorityBlockingQueue、DelayQueue和DelayedWorkQueue
Queue常用类解析之BlockingQueue(二):ArrayBlockingQueue
Queue常用类解析之BlockingQueue(三):LinkedBlockingQueue
接着上文对BlockingQueue的介绍继续向下
七、SynchronousQueue
SynchronousQueue称作同步队列,其不具有任何存放元素的作用,可以将其理解成一个空的队列,size方法固定返回0,peek方法和迭代器操作也都是无意义的。我们不能插入一个新的元素除非有另一个线程在准备移除。
Synchronous支持两种策略模式,分别是公平模式和非公平模式,分别对应TransferQueue(队列)和TransferStack(栈)结构。公平模式先进先出,保证线程的顺序,先请求的线程率先得到响应;非公平模式则是后进先出,后请求的线程率先得到响应。
1. 属性
(1)自旋属性
static final int NCPUS = Runtime.getRuntime().availableProcessors();
static final int maxTimedSpins = (NCPUS < 2) ? 0 : 32;
static final int maxUntimedSpins = maxTimedSpins * 16;
static final long spinForTimeoutThreshold = 1000L;
在SynchronousQueue中,在阻塞之前会先自旋,以减少阻塞带来的代价和消耗。
(2)transfer
private transient volatile Transferer<E> transferer;
核心属性,SynchronousQueue的操作通过transfer完成。
(3)序列化属性
private ReentrantLock qlock;
private WaitQueue waitingProducers;
private WaitQueue waitingConsumers;
2. Transferer
Transferer是SynchronousQueue的内部抽象类,只有一个抽象方法。
/**
* Performs a put or take.
*
* @param e if non-null, the item to be handed to a consumer;
* if null, requests that transfer return an item
* offered by producer.
* @param timed if this operation should timeout
* @param nanos the timeout, in nanoseconds
* @return if non-null, the item provided or received; if null,
* the operation failed due to timeout or interrupt --
* the caller can distinguish which of these occurred
* by checking Thread.interrupted.
*/
abstract E transfer(E e, boolean timed, long nanos);
SynchronousQueue的入队和出队操作都通过该方法完成。
出队时参数e为null,入队时参数e为入队的元素。
timed表示操作是否有超时限制,nanos为具体纳秒表示的超时时间。
take和put时timed为false,nanos为0。
阻塞一段时间的poll和take时timed为true,nanos为具体的阻塞时间。
非阻塞方法时timed为true,nanos为0.
3. TransferStack
TransferStack表示Synchronous的非公平模式,底层结构为栈。
3.1 属性
volatile SNode head;//表示栈的头结点
//节点的3种模式
/** Node represents an unfulfilled consumer */
static final int REQUEST = 0; //出队
/** Node represents an unfulfilled producer */
static final int DATA = 1; //入队
/** Node is fulfilling another unfulfilled DATA or REQUEST */
static final int FULFILLING = 2; //匹配过程中
3.2 SNode
volatile SNode next; // next node in stack //下一个节点
volatile SNode match; // the node matched to this //匹配节点
volatile Thread waiter; // to control park/unpark //节点对于的线程
Object item; // data; or null for REQUESTs //节点的属性,出队时null,入队时入队的对象
int mode; //节点模式
3.3 TransferStack#transfer(Object, boolean, long)
E transfer(E e, boolean timed, long nanos) {
/*
* Basic algorithm is to loop trying one of three actions:
*
* 1. If apparently empty or already containing nodes of same
* mode, try to push node on stack and wait for a match,
* returning it, or null if cancelled.
*
* 2. If apparently containing node of complementary mode,
* try to push a fulfilling node on to stack, match
* with corresponding waiting node, pop both from
* stack, and return matched item. The matching or
* unlinking might not actually be necessary because of
* other th