Java线程池队列LinkedTransferQueue示例详解
刨红薯的小羊竿尔 人气:0正文
public enum QueueTypeEnum { ARRAY_BLOCKING_QUEUE(1, "ArrayBlockingQueue"), LINKED_BLOCKING_QUEUE(2, "LinkedBlockingQueue"), DELAY_QUEUE(3, "DelayQueue"), PRIORITY_BLOCKING_QUEUE(4, "PriorityBlockingQueue"), SYNCHRONOUS_QUEUE(5, "SynchronousQueue"), LINKED_TRANSFER_QUEUE(6, "LinkedTransferQueue"), LINKED_BLOCKING_DEQUE(7, "LinkedBlockingDeque"), VARIABLE_LINKED_BLOCKING_QUEUE(8, "VariableLinkedBlockingQueue"), MEMORY_SAFE_LINKED_BLOCKING_QUEUE(9, "MemorySafeLinkedBlockingQueue"); }
LinkedTransferQueue
无界阻塞队列LinkedTransferQueue,此队列也是基于链表实现,对于所有给定的元素都是先入先出的。LinkedTransferQueue可以算是 LinkedBolckingQueue 和 SynchronousQueue 的合体。SynchronousQueue 内部无法存储元素,当要添加元素的时候,需要阻塞。
LinkedBolckingQueue 则内部使用了大量的锁,性能有所下降。
public class LinkedTransferQueue<E> extends AbstractQueue<E> implements TransferQueue<E>, java.io.Serializable {
相对于其他阻塞队列,LinkedTransferQueue多了 tryTransfer(E e)和transfer(E e) 方法。
public interface TransferQueue<E> extends BlockingQueue<E> { // 如果可能,立即将元素转移给等待的消费者。 // 更确切地说,如果存在消费者已经等待接收它(在 take 或 timed poll(long,TimeUnit)poll)中,则立即传送指定的元素,否则返回 false。 boolean tryTransfer(E e); // 将元素转移给消费者,如果需要的话等待。 // 更准确地说,如果存在一个消费者已经等待接收它(在 take 或timed poll(long,TimeUnit)poll)中,则立即传送指定的元素,否则等待直到元素由消费者接收。 void transfer(E e) throws InterruptedException; // 上面方法的基础上设置超时时间 boolean tryTransfer(E e, long timeout, TimeUnit unit) throws InterruptedException; // 如果至少有一位消费者在等待,则返回 true boolean hasWaitingConsumer(); // 返回等待消费者人数的估计值 int getWaitingConsumerCount(); }
LinkedTransferQueue 消费者线程获取取数据时:调用take poll 等方法
如果队列不为空,则直接取走数据,若队列为空则消费者线程会生成一个占位虚拟节点(节点元素为null)入队,并等待在这个节点上,后面生产者线程请求添加数据时,会从单向链表的head节点开始遍历,如果发现某个节点是一个取数请求任务类型的节点(即是这个节点的isData为false,item == null),生产者线程就不入队了,直接就将元素填充到该节点(元素传递给它),并唤醒该节点等待的消费者线程,被唤醒的消费者线程取走元素。
tryTransfer(E e)方法
tryTransfer(E e) 当生产者线程调用tryTransfer方法时,如果没有消费者等待接收元素,则会立即返回false。该方法和transfer方法的区别就是tryTransfer方法无论消费者是否接收,方法立即返回,而transfer方法必须等到消费者消费后才返回。
tryTransfer(E e, long timeout, TimeUnit unit) 加上了限时等待功能,如果没有消费者消费该元素,则等待指定的时间再返回;如果超时还没消费元素,则返回false,如果在超时时间内消费了元素,则返回true。
transfer(E e)方法
transfer方法,用于将指定元素e传递给消费者线程(调用take/poll方法)。如果有消费者线程正在阻塞等待,则调用transfer方法的线程会直接将元素传递给它;
如果没有消费者线程等待获取元素,则调用transfer方法的线程会将元素插入到队尾,然后阻塞等待,直到出现一个消费者线程获取元素。
加载全部内容