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

目录

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

二.阻塞队列有什么用?

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

四.模拟实现阻塞队列


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

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

1.队列:先进先出

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

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

二.阻塞队列有什么用?

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

举一个现实中的例子

"消息队列"

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

Java多线程阻塞队列(BlockingDeque)的简析_第1张图片

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

就可能导致两个都崩溃掉

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

Java多线程阻塞队列(BlockingDeque)的简析_第2张图片

好处:

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();
    }
}

运行结果

Java多线程阻塞队列(BlockingDeque)的简析_第3张图片

四.模拟实现阻塞队列

第一步实现一个环形队列

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

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;
        }
    }
}

你可能感兴趣的:(java,服务器,网络)