【java并发】java Condition学习

RC电路(一):微分|积分 的取值不同,会导致输出波形和输入波形之间的关系也不同,由此也会产生不同的应用。输出为0,随着电容充满电,运放-输入端得到的分压为正最大值,可等效成一个电压源,且电压不可突变,此时电流反向为最大值,开始充电时的容抗为0,电压不可突变则电压差为0,运放。开始充电时的容抗为0,电压不可突变则电压差为0,运放。输入端得到的分压也不可突变,随着电容放完电,于是。,因电容上电压不能突变(来不及充电,相当于短路,由上分析可得积分运算电路中,输出为运放的负最大峰值,随着电容充满电,输出为运放的正最大峰值,随着电容放完电, 阅读详情

参考:Java并发之Condition

简介

Condition是基于Lock类存在的,也是用于线程的通信,但是是更加细粒度的
Condition的优势是支持多路等待,就是我可以定义多个Condition,每个condition控制线程的一条执行通路。传统方式只能是一路等待。
之后可以使用condition的await()和signal()方法进行线程的通信

使用案例

package lockTest.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * @Author: WalkerShen
 * @DATE: 2022/3/22
 * @Description: 使用condition的await和signal
 **/
public class ConditionTest {
    private static Lock lock=new ReentrantLock();
    private static Condition condition=lock.newCondition();

    public static void main(String[] args) {
        //1、先让线程先执行,调用await方法,获得锁之后再阻塞
        new Thread(()->{
            await();
        },"线程A").start();


        //2、线程B 休眠2s目的是为了让线程A执行await方法阻塞,然后再调用signalAll方法唤醒
        new Thread(()->{
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            signalAll();
        },"线程B").start();

    }


    /**
     * @Author: WalkerShen
     * @DATE: 2022/3/22
     * @Description: 构建await方法
     **/
    private static void await(){
        try {
            String name = Thread.currentThread().getName();
            lock.lock();
            System.out.println(name+"拿到锁");
            System.out.println(name+"等待信号");
            condition.await();
            System.out.println(name+"重新拿到信号");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    /**
     * 通知方法
     */
    private static void signalAll(){
        try {
            String name = Thread.currentThread().getName();
            lock.lock();
            System.out.println(name+"拿到锁");
            condition.signalAll();
            System.out.println(name+"使用signalAll发出信号");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

}

执行结果:

Thread-0拿到锁
Thread-0等待信号
Thread-1拿到锁
Thread-1使用signalAll发出信号
Thread-0重新拿到信号

常用方法

condition可以通俗的理解为条件队列。
当一个线程在调用了await方法以后,直到线程等待的某个条件为真的时候才会被唤醒。这种方式为线程提供了更加简单的等待/通知模式。
Condition必须要配合锁一起使用,因为对共享状态变量的访问发生在多线程环境下。一个Condition的实例必须与一个Lock绑定,因此Condition一般都是作为Lock的内部实现。

  1. await() :造成当前线程在接到信号或被中断之前一直处于等待状态。
  2. await(long time, TimeUnit unit) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  3. awaitNanos(long nanosTimeout) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。返回值表示剩余时间,如果在nanosTimesout之前唤醒,那么返回值 = nanosTimeout - 消耗时间,如果返回值 <= 0 ,则可以认定它已经超时了。
  4. awaitUninterruptibly() :造成当前线程在接到信号之前一直处于等待状态。【注意:该方法对中断不敏感】。
  5. awaitUntil(Date deadline) :造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。如果没有到指定时间就被通知,则返回true,否则表示到了指定时间,返回返回false。
  6. signal() :唤醒一个等待线程。该线程从等待方法返回前必须获得与Condition相关的锁。
  7. signal()All :唤醒所有等待线程。能够从等待方法返回的线程必须获得与Condition相关的锁。

原理简单解析

Condition是AQS的内部类。
每个Condition对象都包含一个队列(等待队列)。

等待队列是一个FIFO的队列,在队列中的每个节点都包含了一个线程引用,该线程就是在Condition对象上等待的线程,如果一个线程调用了Condition.await()方法,那么该线程将会释放锁、构造成节点加入等待队列并进入等待状态。等待队列的基本结构如下所示。

等待分为首节点和尾节点。
当一个线程调用Condition.await()方法,将会以当前线程构造节点,并将节点从尾部加入等待队列。
新增节点就是将尾部节点指向新增的节点。
节点引用更新本来就是在获取锁以后的操作,所以不需要CAS保证。同时也是线程安全的操作。

等待

当线程调用了await方法以后。
线程就作为队列中的一个节点被加入到等待队列中去了。
同时会释放锁的拥有。当从await方法返回的时候。一定会获取condition相关联的锁。当等待队列中的节点被唤醒的时候,则唤醒节点的线程开始尝试获取同步状态。如果不是通过 其他线程调用Condition.signal()方法唤醒,而是对等待线程进行中断,则会抛出InterruptedException异常信息。

通知

调用Condition的signal()方法,将会唤醒在等待队列中等待最长时间的节点(条件队列里的首节点),在唤醒节点前,会将节点移到同步队列中。当前线程加入到等待队列中如图所示:

在调用signal()方法之前必须先判断是否获取到了锁。接着获取等待队列的首节点,将其移动到同步队列并且利用LockSupport唤醒节点中的线程。节点从等待队列移动到同步队列如下图所示:

被唤醒的线程将从await方法中的while循环中退出。随后加入到同步状态的竞争当中去。成功获取到竞争的线程则会返回到await方法之前的状态。

总结

调用await方法后,将当前线程加入Condition等待队列中。
当前线程释放锁。否则别的线程就无法拿到锁而发生死锁。自旋(while)挂起,不断检测节点是否在同步队列中了,如果是则尝试获取锁,否则挂起。当线程被signal方法唤醒,被唤醒的线程将从await()方法中的while循环中退出来,然后调用acquireQueued()方法竞争同步状态。

利用Condition实现生产者消费者模式

生产者

package productConsumerMode.lockAndSignal;

import java.util.List;
import java.util.Random;

public class Producer implements Runnable {
    private List<String> bumList;

    public Producer(List<String> bumList) {
        this.bumList = bumList;
    }

    @Override
    public void run() {

        while (true) {
            try {
                //加锁,记住:condition是需要和lock进行搭配的
                Test.LOCK.lock();
                //若中断则退出循环
                if (Thread.currentThread().isInterrupted()) break;

                //当队列的长度大于等于最大长度的时候,则停止生产,否则则继续生产
                if (bumList.size() >= Test.LENGTH) {
                    System.out.println(Thread.currentThread().getName() + "停止生产包子");
                    //empty通知  full停止
                    Test.EMPTY.signalAll();
                    Test.FULL.await();
                }else{
                    Random random = new Random();
                    int i = random.nextInt(100);
                    bumList.add("包子" + i);
                    System.out.println("【生产者】"+Thread.currentThread().getName()+"生产包子"+i);
                }
                Thread.sleep(1000);

                //解锁
                Test.LOCK.unlock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

消费者

package productConsumerMode.lockAndSignal;

import java.util.List;
/**
 * @Author: WalkerShen
 * @DATE: 2022/3/22
 * @Description: 消费者
 **/
public class Consumer implements Runnable{
    private List<String> bumList;

    public Consumer(List<String> bumList) {
        this.bumList = bumList;
    }


    @Override
    public void run() {
        try {
            //循环
            while(true){
                //线程中断则退出循环
                if(Thread.currentThread().isInterrupted()) break;
                //加锁
                Test.LOCK.lock();
                //队列为空则通知full,empty暂停
                //否则则消费包子
                if(bumList.size()==0){
                    System.out.println("包子已经被消费完了");
                    Test.FULL.signalAll();
                    Test.EMPTY.await();
                }else{
                    String remove = bumList.remove(0);
                    System.out.println("【消费者】"+Thread.currentThread().getName()+"消费"+remove);
                }

                Thread.sleep(1000);
                //解锁
                Test.LOCK.unlock();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

测试

package productConsumerMode.lockAndSignal;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Test {
    //队列长度
    public final static Integer LENGTH=5;

    //新建一个ReentrantLock
    public static ReentrantLock LOCK=new ReentrantLock();
    //之后创建两个condition,分别是队列满,队列空
    public static Condition EMPTY=LOCK.newCondition();
    public static Condition FULL=LOCK.newCondition();

    //包子队列
    static volatile List<String> bumList;


    public static void main(String[] args) {
        bumList=new ArrayList<>();
        Producer producer = new Producer(bumList);
        Consumer consumer = new Consumer(bumList);
        Producer producer1 = new Producer(bumList);
        Consumer consumer1 = new Consumer(bumList);

        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(producer);
        executorService.execute(consumer);
        executorService.execute(producer1);
        executorService.execute(consumer1);
        executorService.shutdown();

    }
}

ResNet改进(45):结合通道混洗(ShuffleNet)的混合架构 本文提出了一种创新的卷积神经网络(CNN)架构CustomResNet,它将ResNet34与通道混洗(ChannelShuffle)技术相结合。该模型通过ShuffleBlock模块替换原始ResNet层,包含三个核心组件:1) ChannelShuffle模块实现通道分组混洗;2) ShuffleBlock模块整合点卷积、分组卷积和残差连接;3) CustomResNet主模型保持ResNet整体架构但替换核心层为ShuffleBlock。这种设计既保留了ResNet的残差学习能力,又通过通道混洗增强特 阅读详情

相关推荐

从MIPS汇编到C语言:手把手教你用Mars模拟器理解指令集(附实战代码)

本文详细介绍了如何使用Mars模拟器从MIPS汇编过渡到C语言编程,通过实战代码解析ADD、LW、BEQ等指令集与C语言结构的对应关系。内容涵盖环境搭建、算术运算、内存访问、条件分支及函数调用等核心概念,帮助读者深入理解MIPS指令分类和计算机底层运行机制。

weixin_26821003的博客 357

Java中的Condition详解

一、Condition简介 任意一个Java对象,都拥有一组监视器方法(定义在Object类中),主要包括wait,notify,notifyAll方法,这些方法与synchornized关键字相配合,可以实现等待/通知模式。 Condition接口也提供了类似的Object的监视器方法,与Lock配合可以实现等待/通知模式。但是这两者在使用方式以及功能上还是有差别的。 Condition定义了等待/通知两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁。Co

向上的"狼"的博客 2万+

Python实战:5分钟搞定滑动平均窗口计算(附完整代码+逐行注释)

本文深入解析Python中滑动平均窗口计算的实现与优化,提供Numpy、Pandas等多种高效方案,并附完整代码和逐行注释。涵盖边界处理、性能优化及异常检测等实战技巧,帮助开发者快速掌握时间序列数据处理的核心技术。

weixin_30872157的博客 124

java中Condition类的详细介绍(详解)

已找不到原文了,还望原文博主看到能告诉小白一下,一定标注原文地址 一 condition 介绍及demo  Conditio...

6339

「点燃我,温暖你」用Python制作一个动态爱心效果

最近「点燃我,温暖你」这部剧非常火,讲述的是程序员的爱情故事。其中陈飞宇饰演的男主李峋,在剧中用程序做出的爱心跳动效果,非常炫。

Modeler_xiaoyu的博客 1万+

Fiddler抓包实战:5分钟搞定微信公众号历史消息接口分析(附完整Python代码)

本文详细介绍了如何使用Fiddler抓包工具逆向分析微信公众号历史消息接口,并提供完整的Python代码实现。从环境准备、动态参数捕获到商业级采集系统架构设计,全面解析了突破官方接口限制的技术方案,帮助开发者高效获取公众号文章数据。

tree8的博客 329

Java并发之Condition详解

一、简介 1. 什么是Condition 任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait()、wait(long timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,但是这两者在使用方式以及功能特性上还是有差别的。——摘自《Java并发编程的艺术》 下面是Cond

weixin_41951205的博客 1416

基于YOLOv8的铁路轨道异物检测系统设计与实现

目标检测是计算机视觉领域的核心任务之一,旨在识别图像中特定目标的位置和类别。传统方法主要依赖手工特征(如HOG、SIFT等)和分类器(如SVM),而深度学习方法通过卷积神经网络自动学习特征表示,显著提升了检测性能。YOLO(You Only Look Once)系列算法作为单阶段目标检测的代表,以其高效的检测速度著称。YOLOv8是Ultralytics公司于2023年发布的最新版本,在精度和速度上都有进一步提升。

YOLO 574

Java并发:Condition详解

2020年在匆匆忙忙慌慌乱乱中就这么度过了,我们迎来了新一年,互联网的发展如此之快,技术日新月异,更新迭代成为了这个时代的代名词,坚持下来的技术体系会越来越健壮,JVM作为如今是跳槽大厂必备的技能,如果你还没掌握,更别提之后更新的新技术了。doSignal方法private void doSignal(Node first) { // 将条件队列的头节点移到同步队列do {

2401_85354228的博客 1053

uniapp:解决微信小程序包体积超过2M的优化方案+详解分包问题,编译小程序体积大于2M不能上传和预览提示体积太大的处理教程,uniApp微信小程序主包过大问题如何解决(排查可疑点+分包+最小改动)

uniapp微信小程序开发,如何解决打包太大无法预览发布的问题,uniApp微信小程序包体积超过2M的优化方法,uni-app打包微信小程序主包超2M终极解决方案,使用uniapp开发微信小程序使用uni_modules导致主包文件过大,无法发布的解决方法,UniApp开发的微信小程序主包过大问题及解决方案 编译小程序时Node-modules被打入主包,小程序体积大于2M不能上传和预览,怎么处理,解决微信小程序主包太大问题,微信小程序中主包和分包过大,详解分包问题,uni-app 微信小程序发布时,主包超

✅ 精选推荐文章 5066

YOLOv11涨点改进 | NeurIPS2025最佳论文!注意力改进篇| 引入Gated Attention门控注意力模块、太牛了!直接拯救了大模型的发展,助力目标检测、图像分割、图像分类有效涨点

本文提出了一种基于门控注意力机制(GatedAttention)的YOLOv11改进方法。该模块通过在标准注意力机制中引入头部特定的sigmoid门控,有效提升了模型性能和训练稳定性。实验表明,GatedAttention能够增强模型对关键信息的聚焦能力,减少无关区域关注,提高检测精度。同时,门控机制带来的非线性和稀疏性优化了计算效率,并缓解了训练不稳定性问题。文章详细介绍了模块原理、实现代码及三种改进方案配置方法,为YOLOv11在复杂场景下的目标检测提供了有效解决方案。

Ai缝合怪、助力小伙伴高效发论文 495

java condition使用及分析

背景:    上一篇文章基于object的wait、notify实现了生产者、消费者模式。本篇文章继续梳理Condition。condition 介绍及demo Condition是在java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition的await()、signal()...

bohu83的博客 2万+

一般无穷积分的收敛判别法

文章目录积分里的狄屎判别法证明阿贝尔判别法总结补充:级数中的狄屎和Abel 积分里的狄屎判别法 F(u)=∫auf(x)dx在[a,+∞)F(u)=\int_a^uf(x)dx在[a,+\infty)F(u)=∫au​f(x)dx在[a,+∞)有界 x→+∞时,g(x)单减→0x\to+\infty时,g(x)单减\rightarrow0x→+∞时,g(x)单减→0 ⇒\Rightarrow⇒ ...

universe_1207的博客 1万+

Java并发学习笔记7 Condition

bilibili-Java并发学习笔记7 Condition 基于 java 1.8.0 P27_Condition详解及相比于传统线程并发模式的改进 public interface Lock { /** * 返回绑定到此 Lock 实例的新 Condition 实例。 * * 在等待条件前,锁必须由当前线程保持。调用 Condition.await() 将在等待前以原子方式释放锁,并在等待返回前重新获取锁。 * * Condition 实例的具体

晨猫 243

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java并发学习笔记 (八) Condition

Java并发学习笔记 (八) Condition 目录 Java并发学习笔记 (七) Condition 一. Condition 简介 二. Condition实现原理 2.1 等待队列 2.2 await实现原理 2.3 signal / signalAll实现原理 Refference 一. Condition 简介 等待通知机制,在Java中主要有两种方...

相遇在梦中的博客 451

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

java condition_java并发编程之深入学习Concurrent包(三,Condition接口)

引言:Condition在Concurrent包中,主要用于替代以前对象Object上的wait()、notify()等方法实现线程间的协作。相比wait()、notify(),Condition根据和Lock的结合,可以实现更复杂和精细的线程协同和等待。Condition包含了接口和在AbstractQueuedSynchronizer类中的ConditionObject类的实现,今天一起学习下...

weixin_39953673的博客 74

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Java并发之Condition详解,从JDK源码学习Hashmap

} catch (Exception e) { } finally { readLock.unlock(); } } /** 唤起线程 */ public void conditionSignal() { readLock.lock(); try { //睡眠5s 线程1启动 Thread.sleep(5000); System.out.println(Thread.currentThread().getName() + “拿到锁了”); condition.signal(); System.out.p

m0_64867092的博客 214

java控制并发流程CountDownLatch、Semaphore、Condition、CyclicBarrier的基础学习

CyclicBarrier和CountDownLatch的区别 ① 作用不同:CyclicBarrier要等固定数量的线程都到达了栅栏位置才能继续执行,而CountDownLatch只需等待数字到0,也就是说,CountDownLatch用于事件,但是CyclicBarrier是用于线程的 ② 可重用性不同:CountDownLatch在倒数到0并触发门闩打开后,就不能再次使用了,除非新建新的实例,而CyclicBarrier可以重复使用

weixin_46665411的博客 895

java condition 例子_java并发编程学习之Condition-用法(一)

Condition主要用await和signal,跟Object的wait、notify差不多用法,只是这里是用lock来替换synchronized。这边复制一下之前的wait和notif例子修改一下示例public class ConditionDemo {Lock lock = new ReentrantLock();Condition condition = lock.newConditi...

weixin_39834205的博客 91

java学习系列-高并发12:JUC中的Condition对象

内容 synchronized中实现线程等待和唤醒 Condition简介及常用方法介绍及相关示例 使用Condition实现生产者消费者 使用Condition实现同步阻塞队列 Object对象中的wait(),notify()方法,用于线程等待和唤醒等待中的线程,大家应该比较熟悉,想再次了解的朋友可以移步到 java学习系列-高并发05:线程的基本操作. synchronized中等待和唤醒线程示例 package com.itsoku.chat09; import java.util.concu

星之宇的博客 275

JAVA并发编程学习7(Condition编程模式详解)

Condition相比于传统线程并发模式的改进 1.传统上,我们可以通过synchronized关键字 + wait + notify/notifyAll 来实现多个线程之间的协调与通信,整个过程都是由JVM来帮助我们实现的;开发者无需(也是无法)了解底层的实现细节 2.从JDK1.5开始,并发包提供了Lock,Condition(await与signal/signalAll)来实现多个线程之间的协调与通信,整个过程都是由开发者来控制的,而且相比于传统方式,更加灵活,功能也更加强大。 3.Thread.

qq_32852017的博客 217

java condition_java并发编程之深入学习lock(一,简介)

Condition接口简介:可带条件的线程通知接口,需要用lock锁一起使用,实现比Object中线程通知方法更精细的控制。Condition中的await()方法类似于Object的wait()方法。Condition中的signal()方法类似于Object的notify()方法。应用场景:线程如果不满足某个Condition将被挂起,而等待中的线程如果满足某个Condition将被唤醒。Lo...

weixin_39872395的博客 81

【Java高并发学习】重入锁ReentrantLock、Condition条件及信号量

本文简单介绍了重入锁以及相关操作、Condition条件与重入锁的结合例子、信号量的作用以及简单例子。

,ლ(′◉❥◉`ლ) 1145

Java并发包源码学习系列:详解Condition条件队列、signal和await

文章目录Condition接口AQS条件变量的支持之ConditionObject内部类回顾AQS中的Nodevoid await()添加到条件队列Node addConditionWaiter()void unlinkCancelledWaiters()完全释放独占锁int fullyRelease(Node node)等待进入阻塞队列boolean isOnSyncQueue(Node node)boolean findNodeFromTail(Node node)void signal()唤醒节点vo

天乔巴夏丶 1302

Java并发20:Lock系列-Condition接口基本方法学习实例

[超级链接:Java并发学习系列-绪论] Lock接口在之前的章节中多次提及,Condition接口在之前的章节中设计不多,只是下面的文章中略有提及: Java并发14:并发三特性-可见性定义、可见性问题与可见性保证技术 本章主要通过解读Condition接口的源码注释,来学习Condition接口的各个方法。 1.Condition接口与Lock接口 在Java并发18章节,我们对...

韩超的博客 (hanchao5272) 1530

关于Java多线程和并发运行的学习(四)——之Condition

关于Java的多线程和并发运行学习了几天

IT一刻钟 746
上一篇: 【java并发】java ReentrantReadWriteLock学习
下一篇: 【java并发】java CopyOnWriteArrayList学习
WalkerShen
WalkerShen 优质创作者: Java技术领域 优质创作者: Java技术领域
博客等级 码龄8年 1万+粉丝 194原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalkerShen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值