1.阻塞队列BlockingQueue
简单介绍:
其实呐,阻塞队列也不是什么比较新的东西,他也是collection下的一种,与set、list等是同一等级的
那什么情况下,在哪种场景下我们会使用到阻塞队列呢?
*多线程并发处理,线程池用的较多的时候
2.四组API.
学会使用四组API —添加、移除(判断队首元素)
四组API对比
注:超时等待中和有返回值的不同处在于 超时等待中offer(E e, long timeout, TimeUnit unit)有三个参数,而poll(long timeout, TimeUnit unit)有两个参数,unit为时间单位,timeout为具体等待时间。
简单代码实现
*1.主方法
在这里插入代码片import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
public class BlockingQueueTest {
public static void main(String[] args) throws InterruptedException {
test1(); //1.抛出异常
//test2();//2.有返回值,不抛出异常
//test3(); //3.阻塞等待
// test4(); //4.超时等待
}
}
*2.无返回值,抛出异常
public static void test1(){
// 队列的大小
ArrayBlockingQueue blockingQueue =
new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a")); // true
System.out.println(blockingQueue.add("b"));// true
System.out.println(blockingQueue.add("c"));// true
// System.out.println(blockingQueue.add("d"));
// IllegalStateException: Queue full 抛出异常---队列已满!
System.out.println("===========================");
System.out.println(blockingQueue.element());//
// 查看队首元素是谁
System.out.println(blockingQueue.remove());//
System.out.println(blockingQueue.remove());//
System.out.println(blockingQueue.remove());//
// System.out.println(blockingQueue.remove());
// java.util.NoSuchElementException 抛出异常---队列已为空!
}
运行结果:
1.正常情况下
2…队列满了,添加不进去
2.对列为空,移除的元素没有
*3.有返回值,但不抛出异常
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"));
System.out.println(blockingQueue.peek());
// false 不抛出异常!
System.out.println("===========================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
// null 不抛出异常!
}
运行结果:
1.正常情况下
2.队列已满,添加不进去
3.队列已为空,移除的元素没有
*3.等待阻塞(一直阻塞)
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());
// 没有这个元素,一直阻塞等待
}
运行结果:
1.正常情况下put()w无返回值
2.对列已满,添加不进去,可以看见程序一直在执行,阻塞中
3.队列已空,移除不了元素,程序也是一直在执行,阻塞中
*4.等待阻塞(超时等待)
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("===============");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
// blockingQueue.poll(2,TimeUnit.SECONDS); // 等待超过2秒就退出
}
执行结果:
1.正常情况下
2.队列已满,添加不进去
3.队列为空,移除不了元素
3.SynchronousQueue 同步队列
没有容量,进去一个元素,必须等待取出来之后,才能再往里面放一个元素!
简单代码实现:
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
/**
* @program: juc
* @description
* @author: 不会编程的派大星
* @create: 2021-04-25 16:23
**/
public class SynchronousQueueTest {
public static void main(String[] args) {
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()+" take "+synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+" take "+synchronousQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+" take "+synchronousQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T2").start();
}
}
运行结果:
放一个取一个,取完一个才能放另一个!
同步队列:
- 和其他的BlockingQueue 不一样, SynchronousQueue 不存储元素
- put了一个元素,必须从里面先take取出来,否则不能在put进去值!
此次讨论就到这里,欢迎小伙伴们留言讨论!