【第八章】JUC之阻塞队列BlokingQueue详解

mac2024-04-15  51

笔记大纲

栈与队列阻塞队列 阻塞队列的好处 BlokingQueue接口的实现类(前3个)BlokingQueue核心方法(4种)BlokingQueue案例应用

一、栈与队列

  栈与队列都是一种数据结构。

  栈:遵循“先进后出”、“后进先出”原则

  队列:遵循“x先进先出”

二、阻塞队列

  阻塞队列是一个队列,它最大的特点就是阻塞的线程满足条件就会被自动唤醒,不需要我们人为的判断。

    当队列为空时,从队列中获取元素的操作就会被阻塞;

    当队列为满时,从队列中添加元素的操作就会被阻塞。

三、阻塞队列的好处

  之前总结的线程间通信,需要判断对应的值增加1减少1,一个生产者与一个消费者,在判断状态的时候需要加一个标志类,还需要控制线程。而阻塞队列在某些情况会挂起<暂停>线程(阻塞),满足条件,就会被自动的唤起,BlokingQueue一手包办!

四、BlokingQueue接口的实现类

序号实现类说明1(重点)ArrayBlockingQueue数据结构组成的有界阻塞队列2(重点)LinkedBlockingQueue链表结构组成的有界阻塞队列(默认大小integer_MAX_VALUE)3(重点)SynchronousQueue不存储元素的阻塞队列(单个元素的队列)4PriorityBlockingQueue支持优先级排序的无界阻塞队列5DelayQueue使用优先级队列实现的延迟无界阻塞队列6LinkedTransferQueue由链表组成的无界阻塞队列。7LinkedBlockingDeque由链表组成的双向阻塞队列。

五、BlokingQueue核心方法

(1)抛出异常

  当阻塞队列满时,再往队列里add插入元素会抛IllegalStateException:Queue full;    当阻塞队列空时,再往队列里remove移除元素会抛NoSuchElementException。

(2)特殊值

  offer插入方法,成功ture失败false;    poll移除方法,成功返回出队列的元素,队列里没有就返回null。

(3)阻塞

  当阻塞队列满时,生产者线程继续往队列里put元素,队列会一直阻塞生产者线程直到put数据或者响应中断退出;    当阻塞队列空时,消费者线程试图从队列里take元素,队列会一直阻塞消费者线程直到队列可用。

六、BlokingQueue案例应用

测试代码1-1(抛出异常方法类型)
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * 阻塞队列(接口) */ public class BlockQueueDemo { public static void main(String[] args) { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 System.out.println(blockingQueue.add("one")); System.out.println(blockingQueue.add("two")); System.out.println(blockingQueue.add("three")); System.out.println(blockingQueue.add("four")); //超出队列初始容量,会报错 } }
打印结果

阻塞队列满时,再往队列里add插入元素会抛IllegalStateException:Queue full

测试代码1-2(抛出异常方法类型)
/** * 阻塞队列(接口)--检查队列 */ public class BlockQueueDemo { public static void main(String[] args) { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 System.out.println(blockingQueue.add("one")); System.out.println(blockingQueue.add("two")); System.out.println(blockingQueue.add("three")); System.out.println(blockingQueue.element()); //查看元素 } }
打印结果

调用element()方法,检查出第一个添加的元素,遵循“先进先出”原则!

测试代码1-3(抛出异常方法类型)
/** * 阻塞队列(接口)--移除元素 */ public class BlockQueueDemo { public static void main(String[] args) { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 System.out.println(blockingQueue.add("one")); System.out.println(blockingQueue.add("two")); System.out.println(blockingQueue.add("three")); System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove());//移除元素,超出队列的容量,报错 } }
打印结果

当阻塞队列空时,再往队列里remove移除元素会抛NoSuchElementException

测试代码2-1(特殊值方法类型)
/** * 阻塞队列(接口)--添加元素offer() */ public class BlockQueueDemo { public static void main(String[] args) { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 System.out.println(blockingQueue.offer("one")); System.out.println(blockingQueue.offer("two")); System.out.println(blockingQueue.offer("three")); System.out.println(blockingQueue.offer("four"));//不抛异常,成功返回true,失败返回false } }
打印结果

测试代码2-2(特殊值方法类型)
/** * 阻塞队列(接口)--移除元素 */ public class BlockQueueDemo { public static void main(String[] args) { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 System.out.println(blockingQueue.offer("one")); System.out.println(blockingQueue.offer("two")); System.out.println(blockingQueue.offer("three")); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll());//成功返回出队列的元素,队列里没有就返回`null` } }
打印结果

测试代码3-1(阻塞方法类型)
/** * 阻塞队列(接口)--移除元素 */ public class BlockQueueDemo { public static void main(String[] args) throws InterruptedException { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 blockingQueue.put("one"); blockingQueue.put("two"); blockingQueue.put("three"); blockingQueue.put("four"); } }
打印结果

…阻塞中,无任何结果!

测试代码3-2(阻塞方法类型)
/** * 阻塞队列(接口)--移除元素 */ public class BlockQueueDemo { public static void main(String[] args) throws InterruptedException { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 blockingQueue.put("one"); blockingQueue.put("two"); blockingQueue.put("three"); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take());//阻塞中,不会结束(不见不散) } }
打印结果

测试代码4-1(超时方法类型)
/** * 阻塞队列(接口)--移除元素 */ public class BlockQueueDemo { public static void main(String[] args) throws InterruptedException { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 System.out.println(blockingQueue.offer("one")); System.out.println(blockingQueue.offer("two")); System.out.println(blockingQueue.offer("three")); //超时3s后,成功返回true,失败返回false System.out.println(blockingQueue.offer("four", 3, TimeUnit.SECONDS)); } }
打印结果

测试代码4-2(超时方法类型)
/** * 阻塞队列(接口)--移除元素 */ public class BlockQueueDemo { public static void main(String[] args) throws InterruptedException { //初始化阻塞队列容量是3 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3); //第一组 System.out.println(blockingQueue.offer("one")); System.out.println(blockingQueue.offer("two")); System.out.println(blockingQueue.offer("three")); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll(3, TimeUnit.SECONDS)); } }
打印结果


 ☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!

☞本人博客:https://coding0110lin.blog.csdn.net/  欢迎转载,一起技术交流吧!

最新回复(0)