笔记大纲
- 栈与队列
- 阻塞队列
- 阻塞队列的好处
- BlokingQueue接口的实现类(前3个)
- BlokingQueue核心方法(4种)
- BlokingQueue案例应用
一、栈与队列
栈与队列都是一种数据结构。
栈:遵循“先进后出”、“后进先出”原则
队列:遵循“x先进先出”
二、阻塞队列
阻塞队列是一个队列,它最大的特点就是阻塞的线程满足条件就会被自动唤醒,不需要我们人为的判断。
当队列为空时,从队列中获取元素的操作就会被阻塞;
当队列为满时,从队列中添加元素的操作就会被阻塞。
三、阻塞队列的好处
之前总结的线程间通信,需要判断对应的值增加1减少1,一个生产者与一个消费者,在判断状态的时候需要加一个标志类,还需要控制线程。而阻塞队列在某些情况会挂起<暂停>线程(阻塞),满足条件,就会被自动的唤起,BlokingQueue一手包办!
四、BlokingQueue接口的实现类
序号 | 实现类 | 说明 |
---|---|---|
1(重点) | ArrayBlockingQueue | 数据结构组成的有界阻塞队列 |
2(重点) | LinkedBlockingQueue | 链表结构组成的有界阻塞队列(默认大小integer_MAX_VALUE ) |
3(重点) | SynchronousQueue | 不存储元素的阻塞队列(单个元素的队列) |
4 | PriorityBlockingQueue | 支持优先级排序的无界阻塞队列 |
5 | DelayQueue | 使用优先级队列实现的延迟无界阻塞队列 |
6 | LinkedTransferQueue | 由链表组成的无界阻塞队列。 |
7 | LinkedBlockingDeque | 由链表组成的双向阻塞队列。 |
五、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/ 欢迎转载,一起技术交流吧!