Java多线程阻塞队列(BlockingDeque)的简析

目录

一.什么是阻塞队列(BlockingDeque)

二.阻塞队列有什么用?

三.运用阻塞队列来实现一个最简单的生产者消费者

四.模拟实现阻塞队列


一.什么是阻塞队列(BlockingDeque)

既然叫做阻塞队列,那么他就满足两个特性

1.队列:先进先出

2.阻塞:空了不让出,满了不让进

  • (1)如果队列为空,尝试出队列,就会出现阻塞,阻塞到队列不为空为止;
  • (2)如果队列满了,尝试入队列,就会出现阻塞,阻塞到队列不为满为止。

二.阻塞队列有什么用?

如果按照课本上的理论来说,就是解耦合,保证两个对象不是强耦合的关系

举一个现实中的例子

"消息队列"

如果我们发送消息没有使用阻塞队列,只是两个对象直接交互的的话是这样

 但是如果一旦A或者B某一方发生了错误之后

就可能导致两个都崩溃掉

所以为了防止这种强耦合的情况发生我们引入一个阻塞队列

好处:

1.即使A或者B某一方崩溃了,那么也不会导致另一方也崩溃(降低耦合)

2.如果在某个时间段内A或者B某一方的数据量激增/极减,但是通过阻塞队列,能保证读取数据不变,保证程序运行的稳定性(削峰填谷)

三.运用阻塞队列来实现一个最简单的生产者消费者

创建两个线程,一个只生产,另一个只消费

public class demo7 {public static BlockingDeque blockingDeque = new LinkedBlockingDeque();public static void main(String[] args) {
//t1是生产者Thread t1 = new Thread(()->{for (int i = 0; i < 5; i++) {
//生产blockingDeque.add(i);System.out.println("我生产了"+i);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});
//t2是消费者Thread t2 = new Thread(()->{for (int i = 0; i < 5; i++) {try {Thread.sleep(1000);
//消费System.out.println("我消费了"+blockingDeque.take());} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();t2.start();}
}

运行结果

四.模拟实现阻塞队列

第一步实现一个环形队列

第二部对进队列和出队列进行加锁和解锁

public class MyBlockingDeque {
//设置一个环形队列private int[] arry = new int[100];private int size = 0 ;private int head = 0;private int tail = 0;private Object lock = new Object();public void put(int key) throws InterruptedException {synchronized (lock){
//如果队列满了就加锁,不让进队列if(size == arry.length){lock.wait();}arry[tail] = key;tail++;
//环形队列if(tail >= arry.length){tail = tail-arry.length;}size++;
//注意解锁免得不能出队列lock.notify();}}public int tack() throws InterruptedException {synchronized (lock){
//如果队列为空,不让出队列,加锁if(size == 0){lock.wait();}int ret = arry[head];head++;
//环形队列if(head > arry.length){head = head -arry.length;}size--;
//注意解锁,免得不能入队列lock.notify();return ret;}}
}

本文链接:https://my.lmcjl.com/post/2462.html

展开阅读全文

4 评论

留下您的评论.