BlockingQueue使用详解以及测试代码

BlockingQueue

另一个Queue,它支持在检索元素时等待队列变为非空,以及在存储元素时等待队列中的空间变为可用的操作。

BlockingQueue方法有四种形式,有不同的处理操作的方式,这些操作不能立即被满足,但可能在将来的某个时候被满足:

  • 第一个 抛出一个异常,

  • 第二个 返回一个特殊值(根据操作的不同,可以是null或false)

  • 第三个 无限期地阻塞当前线程,直到操作成功

  • 第四个 在放弃之前只阻塞给定的最大时间限制。这些方法总结如下表:

image-20220219145033976 image-20220219144853761

image-20220219145118698

BlockingQueueTest
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

class BlockingQueueTest {

    public static void main(String[] args) throws InterruptedException {
        //队列的大小
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        System.out.println(arrayBlockingQueue.add("a"));
        System.out.println(arrayBlockingQueue.add("b"));
        System.out.println(arrayBlockingQueue.add("c"));
        try {
            //java.lang.IllegalStateException: Queue full
            System.out.println(arrayBlockingQueue.add("d"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("----------------------");
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        try {
            //java.util.NoSuchElementException
            System.out.println(arrayBlockingQueue.remove());
        } catch (Exception e) {
            //抛出异常
            e.printStackTrace();
        }

        TimeUnit.SECONDS.sleep(1);
        System.out.println("==============第一阶段测试完毕==============");


        arrayBlockingQueue = new ArrayBlockingQueue(3);
        System.out.println(arrayBlockingQueue.offer("a"));
        System.out.println(arrayBlockingQueue.offer("b"));
        System.out.println(arrayBlockingQueue.offer("c"));
        //offer 不抛出异常
        System.out.println(arrayBlockingQueue.offer("d"));
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        //null 不抛出异常
        System.out.println(arrayBlockingQueue.poll());


        TimeUnit.SECONDS.sleep(1);
        System.out.println("==============第二阶段测试完毕==============");

        arrayBlockingQueue = new ArrayBlockingQueue(3);
        arrayBlockingQueue.put("a");
        arrayBlockingQueue.put("b");
        arrayBlockingQueue.put("c");
        //队列没有位置就会阻塞
        arrayBlockingQueue.put("c");
        System.out.println(arrayBlockingQueue.take());
        System.out.println(arrayBlockingQueue.take());
        System.out.println(arrayBlockingQueue.take());
    }
}

运行结果

true
true

true

a
b
c
java.lang.IllegalStateException: Queue full
at java.util.AbstractQueue.add(AbstractQueue.java:98)
at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
at online.wenmeng.cloudfile.CyclicBarrierTests.main(CloudFileApplicationTests.java:17)
java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at online.wenmeng.cloudfile.CyclicBarrierTests.main(CloudFileApplicationTests.java:27)
第一阶段测试完毕
true
true
true
false
a
b
c
null
第二阶段测试完毕

[第三阶段阻塞,导致没有输出,也不会运行完成]

SynchronousQueueTest
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

class SynchronousQueueTest {

    public static void main(String[] args) throws InterruptedException {
        SynchronousQueue<String> synchronousQueue = new SynchronousQueue<>(); //同步队列

        //写线程
        new Thread(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + "put 1");
                synchronousQueue.put("1");
                System.out.println(Thread.currentThread().getName() + "put 2");
                synchronousQueue.put("2");
                System.out.println(Thread.currentThread().getName() + "put 3");
                synchronousQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "T1").start();

        //读线程
        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
            }
        }, "T2").start();
    }
}

运行结果

T1put 1
T2=>1
T1put 2
T2=>2
T1put 3
T2=>3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值