Java阻塞队列BlockingQueue基础与使用

 更新时间:2023年01月03日 17:22:22   作者:欲无缘  
本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

什么是阻塞队列

阻塞队列本质上还是一种队列,遵循先进先出,后进后出的原则,在此基础上,如果出队时阻塞队列为空,则会使当前线程陷入阻塞,直到入队新元素时通知线程继续执行,如果入队时阻塞队列为满,则会使当前线程陷入阻塞,直到出队旧元素时才通知线程进行执行。

阻塞队列的特点

BlockingQueue不是新的东西

学会使用队列

阻塞队列四组API

方式抛出异常有返回值,不抛出异常阻塞 等待超时等待
添加add(E e)offer(E e)put()offer(E e,Time,TimeUnit)
移除remove()poll()take()poll(Time,TimeUnit)
检测队首元素element()peek
  • 抛出异常是指当队列满时,再次插入会抛出异常(如果队列未满,插入返回值未true);
  • 返回布尔是指当队列满时,再次插入会返回false;
  • 阻塞是指当队列满时,再次插入会被阻塞,直到队列取出一个元素,才能插入。
  • 超时是指当一个时限过后,才会插入或者取出。

抛出异常

/**
* 抛出异常
*/
public static void test1(){
// 队列的大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
// IllegalStateException: Queue full 抛出异常!
// System.out.println(blockingQueue.add("d"));
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
// java.util.NoSuchElementException 抛出异常!
// System.out.println(blockingQueue.remove());
}

有返回值,没有异

/**
* 有返回值,没有异常
*/
public static void test2(){
// 队列的大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
// System.out.println(blockingQueue.offer("d")); // false 不抛出异常!
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll()); // null 不抛出异常!
}

等待,阻塞(一直阻塞)

/**
 * 等待,阻塞(一直阻塞)
 */
public static void test3() throws InterruptedException {
        // 队列的大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        // 一直阻塞
        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        // blockingQueue.put("d"); // 队列没有位置了,一直阻塞
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take())
}

等待,阻塞(等待超时

/**
 * 等待,阻塞(等待超时)
 */
public static void test4() throws InterruptedException {
        // 队列的大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        blockingQueue.offer("a");
        blockingQueue.offer("b");
        blockingQueue.offer("c");
        // blockingQueue.offer("d",2,TimeUnit.SECONDS); // 等待超过2秒就退出
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        blockingQueue.poll(2,TimeUnit.SECONDS); 
}

SynchronousQueue 同步队列

和其他的BlockingQueue 不一样, SynchronousQueue 不存储元素

put了一个元素,必须从里面先take取出来,否则不能在put进去值!

public class SynchronousQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); // 同步队
        // new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+" put 1");
                blockingQueue.put("1");
                System.out.println(Thread.currentThread().getName()+" put 2");
                blockingQueue.put("2");
                System.out.println(Thread.currentThread().getName()+" put 3");
                blockingQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"T1").start();
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"T2").start();
    }
}

到此这篇关于Java阻塞队列BlockingQueue基础与使用的文章就介绍到这了,更多相关Java BlockingQueue内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中添加按钮并添加响应事件的方法(推荐)

    java中添加按钮并添加响应事件的方法(推荐)

    下面小编就为大家带来一篇java中添加按钮并添加响应事件的方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • 一文搞清楚Java中Comparable和Comparator的区别

    一文搞清楚Java中Comparable和Comparator的区别

    Java中的Comparable和Comparator都是用于集合排序的接口,但它们有明显的区别,文中通过一些实例代码详细介绍了Java中Comparable和Comparator的区别,感兴趣的同学跟着小编一起学习吧
    2023-05-05
  • java获取文件编码,jsoup获取html纯文本操作

    java获取文件编码,jsoup获取html纯文本操作

    这篇文章主要介绍了java获取文件编码,jsoup获取html纯文本操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 详解Spring Boot中整合Sharding-JDBC读写分离示例

    详解Spring Boot中整合Sharding-JDBC读写分离示例

    这篇文章主要介绍了详解Spring Boot中整合Sharding-JDBC读写分离示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • ChatGPT介绍及Java API调用

    ChatGPT介绍及Java API调用

    本文主要介绍了ChatGPT介绍及Java API调用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Java 构造器原理及用法解析

    Java 构造器原理及用法解析

    这篇文章主要介绍了Java 构造器原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java中LinkedHashSet的实现原理详解

    Java中LinkedHashSet的实现原理详解

    这篇文章主要介绍了Java中LinkedHasSet的实现原理详解,LinkedHashSet 是具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现,此实现与HashSet 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表,需要的朋友可以参考下
    2023-09-09
  • springboot配置文件的加载顺序解析

    springboot配置文件的加载顺序解析

    这篇文章主要介绍了springboot配置文件的加载顺序解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • SpringBoot入口类和@SpringBootApplication讲解

    SpringBoot入口类和@SpringBootApplication讲解

    这篇文章主要介绍了SpringBoot入口类和@SpringBootApplication讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Mybatis实现单个和批量定义别名typeAliases

    Mybatis实现单个和批量定义别名typeAliases

    这篇文章主要介绍了Mybatis实现单个和批量定义别名typeAliases,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论