阻塞queue系列之LinkedTransferQueue

本文深入介绍了JDK7中新增的LinkedTransferQueue,一种无界FIFO线程安全的阻塞队列。通过双重数据结构实现了生产者与消费者的高效协作。探讨了transfer、tryTransfer等方法的使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LinkedTransferQueue在JDK7 中新增的。无界FIFO线程安全的阻塞队列。
transfer 算法比较复杂,实现很难看明白。大致的理解是采用所谓双重数据结构 (dual data structures) 。之所以叫双重,其原因是方法都是通过两个步骤完成:保留与完成。比如消费者线程从一个队列中取元素,发现队列为空,他就生成一个空元素放入队列 , 所谓空元素就是数据项字段为空。然后消费者线程在这个字段上旅转等待。这叫保留。直到一个生产者线程意欲向队例中放入一个元素,这里他发现最前面的元素的数据项字段为 NULL,他就直接把自已数据填充到这个元素中,即完成了元素的传送。大体是这个意思,这种方式优美了完成了线程之间的高效协作。

构造方法

 public LinkedTransferQueue() {
    }

public LinkedTransferQueue(Collection<? extends E> c) {
        this();
        addAll(c);
    }

常用方法

tryTransfer:


/**
     *  不阻塞
     *  @return  true   有 消费者 等待消费
     *  @return  false  无 消费者 等待消费
     */
    @Test
    public void tryTransfer() {
        boolean b = queue.tryTransfer(1);
        System.out.println(b);
    }

transfer:

/**
     *  transfer,阻塞,直到有消费者消费,才能插入
     *  注意:只能消费,不能使用peek等(peek只是取出,并未消费),不然一直等待
     *
     *  take:一直阻塞
     *  poll: 不阻塞,拿不到值,返回null
     *
     *  还有个重载:tryTransfer(E e, long timeout, TimeUnit unit)
     */
    @Test
    public void transfer() throws InterruptedException {
        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(queue.take());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 2, TimeUnit.SECONDS);
        queue.transfer(1);
      //  System.out.println("----" + queue.size());
    }

/**
     * add offer put 这三个方法都是调用xfer(e, true, ASYNC, 0)
     * 只能return不一样,都是直接插值,无阻塞
     * @throws InterruptedException
     */
    @Test
    public void addofferput() throws InterruptedException {
        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println(queue.take());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 2, TimeUnit.SECONDS);
        queue.add(1);
        System.out.println("--=====--" + queue.size());
        queue.offer(2);
        System.out.println("--=====--" + queue.size());
        queue.put(3);
        System.out.println("--=====--" + queue.size());
        TimeUnit.SECONDS.sleep(3);
        System.out.println("--=====--" + queue.size());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值