首页 > 编程语言 >JUC并发编程:基于Condition实现一个阻塞队列

JUC并发编程:基于Condition实现一个阻塞队列

时间:2024-07-28 14:53:28浏览次数:17  
标签:JUC 队列 lock 编程 阻塞 datalist 线程 Condition

Condition方法概述

await(): 当前线程进入等待状态,直到被通知(siginal)或中断【和wait方法语义相同】。

awaitUninterruptibly(): 当前线程进入等待状态,直到被通知,对中断不敏感。

awaitNanos(long timeout): 当前线程进入等待状态直到被通知(siginal),中断或超时。

awaitUnitil(Date deadTime): 当前线程进入等待状态直到被通知(siginal),中断或到达某个时间。

signal(): 唤醒一个等待在Condition上的线程,该线程从等待方法返回前必须获得与Condition关联的锁【和notify方法语义相同】

signalAll(): 唤醒所有等待在Condition上的线程,能够从等待方法返回的线程必须获得与Condition关联的锁【和notifyAll方法语义相同】。

实现阻塞队列

基于自定义互斥锁,实现阻塞队列。阻塞队列具有两个特点:
添加元素到队列中, 如果队列已满会使得当前线程阻塞【加入到条件队列-队列不满】,直到队列不满为止
移除队列中的元素,当队列为空时会使当前线程阻塞【加入到条件队列-队列不空】,直到队列不为空为止
上一篇中的互斥锁:
https://blog.csdn.net/m0_59925573/article/details/140748134?spm=1001.2014.3001.5501

//基于上一篇实现的互斥锁实现阻塞队列
//阻塞队列的特点 如果队列已满当前线程会阻塞知道唤醒
//移除队列中的元素,当队列为空的使当前线程阻塞
@Slf4j
public class BoundedBlockingQueue<T> {
    private List<T> datalist;
    private int size;
    private MyLock lock;

    private Condition notEmpty;
    private Condition notFull;

    public BoundedBlockingQueue(int size){
        this.datalist = new ArrayList<>();
        this.size = size;
        lock = new MyLock();
        notEmpty = lock.newCondition();
        notFull = lock.newCondition();
    }
    //向队列中添加元素
    public void add(T data) {
        lock.lock();
        try {
            //如果队列已经满了 保持等待
            while (datalist.size() == size){
                notFull.await();
            }
            datalist.add(data);
            System.out.println("add success" + data);
            notEmpty.signal();
        }catch (InterruptedException e){
            log.error("add{}",e.getMessage());
        }finally {
            lock.unlock();
        }
    }
    //移除队列中的第一个元素
    public void remove() {
        lock.lock();
        try {
            while (datalist.isEmpty()){
                notFull.await();
            }
            T t = datalist.get(0);
            datalist.remove(0);
            System.out.println("remove success" + t);
            notFull.signal();
        }catch (InterruptedException e){
            log.error("remove{}",e.getMessage());
        }finally {
            lock.unlock();
        }
    }
}

标签:JUC,队列,lock,编程,阻塞,datalist,线程,Condition
From: https://blog.csdn.net/m0_59925573/article/details/140750827

相关文章

  • 【python】网络通信编程例子
    以下是一个简单的Python示例,展示了如何在Linux下使用套接字进行基本的网络通信,包括创建服务器和客户端。服务器端代码importsocket#创建一个IPv4TCP套接字server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#绑定服务器地址和端口server_addr......
  • 在SQL编程中DROP、DELETE和TRUNCATE的区别
    在SQL编程中,DROP、DELETE和TRUNCATE都是用于删除数据的命令,但它们之间有着显著的区别,主要体现在它们删除数据的范围、操作的不可逆性、对表结构的影响、性能以及事务日志的影响上。DROP:作用:DROP命令用于删除整个表及其所有的数据、索引、触发器、约束等。简而言之,它会从......
  • 模块3 面向对象编程高级 --- 第十章:实现多态
    第十章实现多态主要知识点1、多态的定义2、实现多态的条件学习目标理解多态的含义,掌握多态的使用方法,所谓多态:多种状态。在面向对象语言中,接口中定义的抽象方法的多种不同实现方式即多态。10.1创建多态的条件10.1.1多态的定义首先多态的作用是什么呢?......
  • stable diffusion中的UNet2DConditionModel代码解读
    UNet2DConditionModel总体结构图片来自于https://zhuanlan.zhihu.com/p/635204519stablediffusion运行unet部分的代码。noise_pred=self.unet(sample=latent_model_input,#(2,4,64,64)生成的latenttimestep=t,#时刻tencoder_hidden_states=pro......
  • 画nyquis图的一个小编程技巧
    开环传递函数G(s)=(10*K)/(s*(s+5)*(0.1*s+1)),当k分别为17.5 20时,画出对应的nyquist图代码如下:%plotnyquistofthecontrolsystemopen-looptransferfunctionG(s)=(10*K)/(s*(s+5)*(0.1*s+1));K=[17.520];den=conv([10],conv([15],[0.11]));num=[000];Re=......
  • pythonasm库分析,看看你和自学编程小学生的差距
    下面是pythonasm.asm库的源代码fromkeystoneimport*fromcapstoneimport*assembly_instructions=[]#储存汇编指令的列表#汇编指令写入列表defmov(reg1,reg2):assembly_instructions.append(f"mov{reg1},{reg2}")defdb(value):assembly_instructio......
  • Matlab编程资源库(10)离散傅立叶变换
    一、离散傅立叶变换算法简要给定一个N点的离散信号序列x(n),其中n表示时刻,n=0,1,2,...,N-1。定义离散傅立叶变换的频域序列X(k),其中k表示频率,k=0,1,2,...,N-1。通过以下公式计算每个频率对应的复数值: X(k)=Σx(n)*exp(-j*2π*kn/N),其中j表示虚......
  • Matlab编程资源库(11)多项式计算
    一、多项式的四则运算1.多项式的加减运算2.多项式乘法运算   函数conv(P1,P2)用于求多项式P1和P2的乘积。这里,P1、P2是两个多项式系数向量。3.多项式除法   函数[Q,r]=deconv(P1,P2)用于对多项式P1和P2作除法运算。其中Q返回多项式P1除以P2的商式,r返回P1除以......
  • Matlab编程资源库(9)数据插值与曲线拟合
    一、一维数据插值    在MATLAB中,实现这些插值的函数是interp1,其调用格式为:Y1=interp1(X,Y,X1,'method')    函数根据X,Y的值,计算函数在X1处的值。X,Y是两个等长的已知向量,分别描述采样点和样本值,X1是一个向量或标量,描述欲插值的点,Y1是一个与X1等长的插值结......
  • 编程语言之泛型困境
    困境泛型不可能三角泛型困境的本质是,关于泛型,你想要缓慢的程序员、缓慢的编译器和臃肿的二进制文件,还是缓慢的执行时间。简单来说就是:要么苦了程序员,要么苦了编绎器,要么降低运行时效率。不同语言对泛型的考量以C、C++和Java为例,它们在泛型的设计上有着不同考量:C语言:是系统......