阻塞队列(多线程)

阻塞队列是带有阻塞功能且线程安全的队列.(即,队列为空,尝试出队列,出队列操作就会阻塞等待一直阻塞到队列不为空为止,队列为满,入队操作就会阻塞等待一直阻塞到队列不满为止.) 阻塞队列的作用之一就是可以实现生产者消费者模型,有两方面的作用1.能够让程序解耦合 2.能够实现"削峰填谷".

首先使用标准库提供的阻塞队列.

复制代码
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo1 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        //消费者
        //put带有阻塞功能的入队列  take带有阻塞功能的出队列
        Thread t1=new Thread(()->{
            while(true) {
                int value;
                try {
                    value = queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费的:" + value);

            }
        });
        Thread t2=new Thread(()-> {
            int count=1;
            while (true) {
                try {
                    queue.put(count);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("生产的:"+count);
                count++;
            }
        });
        t1.start();
        t2.start();
    }
}
//由于对生产和消费没有限制虽然限制了队列的大小是10,所以没有体现出阻塞功能.

import java.sql.SQLOutput;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo2 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        //生产者
        Thread t1=new Thread(()->{
            int count=1;
            while(true){
                try {
                    queue.put(count);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("生产者:"+count);
                count++;
            }
            //如果对消费者的速度进行限制,那么会使阻塞队列满

        });
        //消费者
        Thread t2=new Thread(()->{
            int value;
            while(true){
                try {
                    value=queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费者:"+value);
            }
        });
        //这里消费者是一秒钟消费一次,因此在进行出队列的时候会发生阻塞
        //且队列中只有10个元素.
        t1.start();
        t2.start();
    }
}

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo3 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        Thread t1=new Thread(()->{
            int count=1;
           while(true) {
               try {
                   queue.put(count);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("生产者:"+ count);
               count++;
           }
        });
        Thread t2=new Thread(()->{
            int value;
            while(true){
                try {
                    value=queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费者:"+value);
            }
        });
        //这一次是没有对生产者进行限制,因此消费者的节奏会跟着生产者.
        t1.start();
        t2.start();
    }
}

接下来自己实现一个带有阻塞功能的队列.

复制代码
//自己实现阻塞队列
class MyblockingQueue{
    //自己实现阻塞队列
    //设置一个队列是存储整形的
    private int[] elems=null;
    //[head,tail)
    //head是头结点,tail是尾结点
    //开始的时候,头结点和尾结点都是0,size也是0
    private int head=0;
    private int tail=0;
    private int size=0;
    //构造方法
    public MyblockingQueue(int capacity){
        elems=new int[capacity];
    }
    //下面写入队列操作
    void put(int elem) throws InterruptedException {
        //首先要判断队列是否满
        synchronized(this) {
            while (size >= elems.length) {
                this.wait();
                //如果队列满了就要进行阻塞操作
                //一定要进行返回等待,等待出队列操作的执行
                return;
            }
            //队列没有满入队列时
            //尾结点指向的空间没有存储元素
            elems[tail] = elem;
            tail++;
            if (tail >= elems.length) {
                tail = 0;
                //到达了队列的末尾就要回到开头
            }
            size++;
            this.notify();
        }
    }
  //出队列操作
    int take() throws InterruptedException {
        synchronized(this) {
            //还是要先判断队列是否是空,如果为空,就要阻塞等待
            while (size == 0) {
                this.wait();
                return -99999;
            }
            //出队列操作
            int result = elems[head];
            head++;
            if (head >= elems.length) {
                head = 0;
            }
            size--;
            this.notify();
            return result;
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        MyblockingQueue tt=new MyblockingQueue(10);
        Thread t1=new Thread(()->{
            int count=0;
           while(true){
               try {
                   tt.put(count);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("生产者: "+count);
               count++;
           }
        });
        Thread t2=new Thread(()->{
           int value;
           while(true){
               try {
                   value=tt.take();
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("消费者: "+value);
           }
        });
        t1.start();
        t2.start();
    }

}
相关推荐
漫步者TZ7 分钟前
【StarRocks系列】StarRocks vs Mysql
数据库·starrocks·mysql·分布式数据库
Love__Tay18 分钟前
【Python小练习】3D散点图
开发语言·python·3d
Java初学者小白18 分钟前
秋招Day14 - MySQL - SQL优化
java·数据库·sql·mysql
Cyanto39 分钟前
Tomcat双击startup.bat闪退的解决方法
java·tomcat
iCxhust1 小时前
一款复古的Intel8088单板机制作
开发语言·单片机·嵌入式硬件
武昌库里写JAVA1 小时前
Vue状态管理实践:使用Vuex进行前端状态管理
java·vue.js·spring boot·课程设计·宠物管理
豆沙沙包?1 小时前
2025年- H83-Lc191--139.单词拆分(动态规划)--Java版
java·算法·动态规划
lovebugs1 小时前
百万并发下的生存之道:Java秒杀系统架构设计全解析
java·后端·架构
神洛华1 小时前
SQL Server基础语句2:表连接与集合操作、子查询与CET、高级查询
数据库·sql