首页 > 其他分享 >手写简单生产者消费者阻塞队列

手写简单生产者消费者阻塞队列

时间:2023-11-07 16:44:23浏览次数:32  
标签:Thread 队列 lock 阻塞 new 手写 final blockQueue

主要实现生产者定时生产,消费者只要队列消息中有就消费。

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ProductConsumerQueue<E> {
    private final Queue<E> blockQueue;
    private final ReentrantLock lock;//锁
    private Integer MAX_SIZE = 20;
    private final Condition notFull;
    private final Condition notEmpty;
    ProductConsumerQueue(Integer capacity){
        lock = new ReentrantLock();
        blockQueue = new LinkedList<>();
        MAX_SIZE = capacity;
        notFull = lock.newCondition();
        notEmpty = lock.newCondition();
    }
    public void put(E element) throws InterruptedException {
        if(Objects.isNull(element)) {//消息不能为空
            throw new IllegalArgumentException("blockQueue put element is null");
        }
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();//尝试获取锁,若没获取到在等待期间,可被interrupt()中断该等待过程
        try {
            while(blockQueue.size()==MAX_SIZE){//队列是否已满,满则等待队列不为空
                notFull.await();
            }
            blockQueue.add(element);//入队
            notEmpty.signal();//唤起等待队列不为空的线程
        }finally {
            lock.unlock();//解锁
        }
    }

    public E poll() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try{
            if(blockQueue.size()==0){//判断是否为空,为空则等待队列不为空,也可直接返回null,可根据需要自行更改策略
                notEmpty.await();
            }
            E e =blockQueue.poll();//出队
            notFull.signal();//唤醒等待队列未达到最大容量的线程
            return e;
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ProductConsumerQueue<Integer> queue = new ProductConsumerQueue<>(1024);
        AtomicInteger nums = new AtomicInteger(0);//原子类,线程安全
        Thread product = new Thread(()->{
            while(true){
                try {
                    Thread.sleep(200);//定时生产
                    int num = nums.getAndIncrement();
                    queue.put(num);
                    System.out.println("product enqueue"+num);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread consumer = new Thread(()->{
           while(true){
               try {
                   Integer num = queue.poll();
                   System.out.println("consumer dequeue"+num);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        consumer.start();
        product.start();
    }
}

标签:Thread,队列,lock,阻塞,new,手写,final,blockQueue
From: https://www.cnblogs.com/lazy-brain/p/17815349.html

相关文章

  • [左神面试指南] 栈和队列篇
    CD5设计一个有getMin功能的栈/**维护一个最小栈minStack*dataStack每压入一个数,minStack也压入一个当前状态的最小值*/publicclassCD5_1{publicstaticclassSolution{publicStack<Integer>dataStack=newStack<>();publicSt......
  • 数据结构-队列和栈
    栈和队列是两种不同的数据形式,区别就是栈是先进后出,但是队列先进先出,可以用数据结构模拟这两种形式。1、队列完整代码如下:#include<stdio.h>#include<stdlib.h>#if0/*顺序队列*/intenQueue(int*a,intrear,intdata){a[rear]=data;rear++;retur......
  • 数据结构-队列
    一、概念1、队列的定义队列是仅限在一端进行插入,另一端进行删除的线性表。队列又被称为先进先出(FirstInFirstOut)的线性表,简称FIFO。2、队首允许进行元素删除的一端称为队首3、队尾允许进行元素插入的一端称为队尾二、接口1、可写接口(1)数据入队队列的插入操作,叫做入队。它是......
  • 单调队列学习笔记
    Menu单调队列(MonotonicQueue)简介代码模板例题单调栈(MonotonicStack)简介代码模板例题......
  • 队列(阻塞队列、非阻塞队列)的详解
    队列的详解什么是队列?用来存储一条条消息(线程)的容器是一个对列。队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则什么是阻塞队列,什么是非阻塞队列?阻塞队列:添加元素时,超过总数则会进行等待(阻塞)。删除元素时,队列为空则会进行等待(阻塞)。非阻塞队列:不管什么情况下都......
  • java IO流:介绍下阻塞、非阻塞、同步、异步 I/O 的概念
    这里先介绍下阻塞、非阻塞、同步、异步I/O的概念。先来看看阻塞I/O,当用户程序执行read,线程会被阻塞,一直等到内核数据准备好,并把数据从内核缓冲区拷贝到应用程序的缓冲区中,当拷贝过程完成,read才会返回。注意,阻塞等待的是「内核数据准备好」和「数据从内核态拷贝到用户态」这两......
  • 栈和队列的应用
    栈和队列的应用栈的应用逆序输出栈的逆序输出应该是栈最简单的应用了,由于栈的先进后出的特点,我们很自然地想到将输入序列按顺序压入栈中,在将所有元素压入栈中以后,再从栈顶依次弹出所有元素,这样就得到了一个被逆置的序列。下面我们进行一个约定:用<表示栈顶,用]表示栈底,如\(<1,......
  • 队列(Queue):先进先出(FIFO)的数据结构
    队列是一种基本的数据结构,用于在计算机科学和编程中管理数据的存储和访问。队列遵循先进先出(FirstIn,FirstOut,FIFO)原则,即最早入队的元素首先出队。这种数据结构模拟了物理世界中的队列,如排队等待服务的人。在本篇博客中,我们将详细介绍队列的概念、用途、实现以及如何在编程中......
  • JUC并发编程学习笔记(九)阻塞队列
    阻塞队列阻塞队列队列的特性:FIFO(fistinpuptfistoutput)先进先出不得不阻塞的情况什么情况下会使用阻塞队列:多线程并发处理、线程池学会使用队列添加、移除四组API方式抛出异常不抛出异常,有返回值阻塞等待超时等待添加addofferputoffer(Ee,lo......
  • 如何使用Event事件对异步线程进行阻塞和放行?
    //定义信号事件staticAutoResetEventautoResetEvent=newAutoResetEvent(false);//定义要异步执行的方法staticvoidA()    {        for(inti=0;i<10;i++)        {            autoResetEvent.WaitOne();//阻塞等待信号......