Java线程池队列LinkedTransferQueue示例详解

 更新时间:2022年12月12日 16:45  点击:224 作者:刨红薯的小羊竿尔

正文

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),生产者线程就不入队了,直接就将元素填充到该节点(元素传递给它),并唤醒该节点等待的消费者线程,被唤醒的消费者线程取走元素。

image.png

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方法的线程会将元素插入到队尾,然后阻塞等待,直到出现一个消费者线程获取元素。

以上就是Java线程池队列LinkedTransferQueue示例详解的详细内容,更多关于Java LinkedTransferQueue的资料请关注猪先飞其它相关文章!

原文出处:https://juejin.cn/post/7175157905539366971

[!--infotagslink--]

相关文章