阻塞队列(多线程)

阻塞队列是带有阻塞功能且线程安全的队列.(即,队列为空,尝试出队列,出队列操作就会阻塞等待一直阻塞到队列不为空为止,队列为满,入队操作就会阻塞等待一直阻塞到队列不满为止.) 阻塞队列的作用之一就是可以实现生产者消费者模型,有两方面的作用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();
    }

}
相关推荐
Y3815326622 小时前
MySQL 慢查询排查实战:EXPLAIN 看懂 type 与 Extra,一个字段定位性能问题
数据库·mysql
kruptos3 小时前
分布式系统怎么“选主“?Raft 共识一次讲清
开发语言·分布式·php·共识算法
xcl09253 小时前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
吴声子夜歌3 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
小小猪的春天3 小时前
Java 手写第一个 MCP Server:Spring AI MCP 半小时跑通
java·人工智能·spring boot·ai编程
find1star3 小时前
LeetCode 141:环形链表
java·算法·leetcode·链表
Logintern094 小时前
PostgreSQL 的 ORDER BY 多列排序
数据库·postgresql
今天AI了吗4 小时前
DeepSeek Harness 深度解析:从评测架构到实战落地
java·网络·数据库·人工智能·架构·java-ee
benchmark_cc4 小时前
REST API 和 Python SDK 应该怎么选?量化交易数据接口选型实战
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
王的宝库4 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang