多线程案例(2) - 阻塞队列

目录

一,阻塞队列

1.1 什么是阻塞队列

1.2 生产者消费者模型

1.3 标准库中的阻塞队列

1.4 阻塞队列的实现


一,阻塞队列

1.1 什么是阻塞队列

阻塞队列(BlockingQueue)是一种特殊的队列,遵循 "先进先出" 的原则,它有两个特点:1. 队列为空时等待获取元素。2. 队列已满时等待插入元素的操作。具体来说,当一个线程试图从空的阻塞队列中获取元素时,该线程将被阻塞,直到队列中有可用元素为止。同样地,当一个线程试图向已满的阻塞队列中插入元素时,该线程将被阻塞,直到队列中有空闲位置为止。

1.2 生产者消费者模型

阻塞队列通常用于实现生产者-消费者模式,其中生产者线程将数据放入队列,而消费者线程从队列中取出数据进行处理。那么这么做有什么好处呢?

  1.  阻塞队列类似于一个缓冲区,可以平衡生产者和消费者的处理能力,比如:在318,双11这些日子的时候,服务器会在同一时刻收到大量的购物订单,如果一股脑的交给一个服务器可能扛不住,这个时候就可以把这些订单放入到阻塞队列中,然后再由服务器慢慢处理每个订单,再举一个生活中的例子,三峡大坝(阻塞队列),当汛期到来时,三峡大坝会将多余的水储存住,防止下游出现洪涝灾害,等到枯水期的时候,再将储存的水排到下游,起到了 "削峰填谷" 的作用。
  2. 能够使代码解耦合,简单来说,就是降低代码之间的联系,这样就不会出现 "牵一发而动全身" 的现象。

1.3 标准库中的阻塞队列

标准库中提供了一个BlockingQueue的接口,它继承了Queue类,所以它包含Queue的所有方法,常见的阻塞队列实现包括ArrayBlockingQueue、LinkedBlockingQueue等。我们通常使用这些类中的 put() 和 take() 方法,因为其他的方法不具备 "阻塞" 特性。

import java.util.concurrent.*;
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>();
        blockingQueue.put("111");
        String t = blockingQueue.take();
    }
}

1.4 阻塞队列的实现

这里我们使用循环数组的方式来实现阻塞队列。

public class MyBlockingQueue {
    private int[] arr = new int[10];//队列
    //防止出现内存可见性的问题
    private volatile int head;//头
    private volatile int tail;//尾
    private volatile int size;//已经存了几个元素
    public MyBlockingQueue(){
        head = 0;
        tail = 0;
        size = 0;
    }
    public void put(int val) throws InterruptedException {
        synchronized (this){
            if(size == arr.length){
                this.wait();//队列满了,阻塞
            }
            arr[tail] = val;
            tail = (tail+1)%arr.length;
            size++;
            this.notify();//唤醒take()中的wait()
        }
    }
    public int take() throws InterruptedException {
        synchronized (this) {
            if(size == 0){
                this.wait();//队列为空,阻塞
            }
            int tmp = arr[head];
            head = (head+1)%arr.length;
            size--;
            this.notify();//唤醒put()中的wait()
            return tmp;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m0_74859835/article/details/132866456