(一)并发工具类Lock与Condition

Java并发Lock和Condition 文章目录一.简介二.原理2.1 管程2.2 可见性2.3 可重入锁2.4 公平锁与非公平锁2.5 用锁的最佳实践2.6 示例 一.简介 Java SDK并发包通过Lock和Condition两个接口来实现管程,其中Lock用于解决互斥问题,Condition 用于解决同步问题。 二.原理 2.1 管程 在 Java 的 1.5 版本中,synchronized 性能不如 SDK 里面的 Lock,但 1.6 版本之后,synchronized 做了很多优化,将性能追了上来,所以 1.6 之后的版本又有人推荐 阅读详情

Lock(互斥)与Condition(管程)

概述

并发编程领域,有两大核心问题:一个是互斥,即同一时刻只允许一个线程访问共享资源;另一个是同步,即线程之间如何通信、协作。这两大问题,管程都是能够解决的。Java SDK 并发包通过 Lock 和 Condition 两个接口来实现管程,其中 Lock 用于解决互斥问题,Condition 用于解决同步问题。

为什么不用synchronized?

因为synchronized无法破坏死锁中的请求与保持条件, synchronized 申请资源的时候,如果申请不到,线程直接进入阻塞状态。

因此提出了三种方案分别对应Lock里的方法实现

  1. 能够响应中断:synchronized 的问题是,持有锁 A 后,如果尝试获取锁 B 失败,那么线程就进入阻塞状态,一旦发生死锁,就没有任何机会来唤醒阻塞的线程。但如果阻塞状态的线程能够响应中断信号,也就是说当我们给阻塞的线程发送中断信号的时候,能够唤醒它,那它就有机会释放曾经持有的锁 A。这样就破坏了不可抢占条件了。
  2. 支持超时。如果线程在一段时间之内没有获取到锁,不是进入阻塞状态,而是返回一个错误,那这个线程也有机会释放曾经持有的锁。这样也能破坏不可抢占条件。
  3. 非阻塞地获取锁。如果尝试获取锁失败,并不进入阻塞状态,而是直接返回,那这个线程也有机会释放曾经持有的锁。这样也能破坏不可抢占条件。
// 支持中断的API
void lockInterruptibly() 
  throws InterruptedException;
// 支持超时的API
boolean tryLock(long time, TimeUnit unit) 
  throws InterruptedException;
// 支持非阻塞获取锁的API
boolean tryLock();

## 保证可见性 利用了 volatile 相关的 Happens-Before 规则。Java SDK 里面的 ReentrantLock,内部持有一个 volatile 的成员变量 state,获取锁的时候,会读写 state 的值;解锁的时候,也会读写 state 的值(简化后的代码如下面所示)。也就是说,在执行 value+=1 之前,程序先读写了一次 volatile 变量 state,在执行 value+=1 之后,又读写了一次 volatile 变量 state。

可重入

所谓可重入锁,顾名思义,指的是线程可以重复获取同一把锁。当线程 T1 执行到 ① 处时,已经获取到了锁 rtl ,当在 ① 处调用 get() 方法时,会在 ② 再次对锁 rtl 执行加锁操作。此时,如果锁 rtl 是可重入的,那么线程 T1 可以再次加锁成功;如果锁 rtl 是不可重入的,那么线程 T1 此时会被阻塞。

class X {
  private final Lock rtl =
  new ReentrantLock();
  int value;
  public int get() {
    // 获取锁
    rtl.lock();        1
    try {
      return value;
    } finally {
      // 保证锁能释放
      rtl.unlock();
    }
  }
  public void addOne() {
    // 获取锁
    rtl.lock();  
    try {
      value = 1 + get(); 1
    } finally {
      // 保证锁能释放
      rtl.unlock();
    }
  }
}

拓展可重入函数:可重入函数,指的是多个线程可以同时调用该函数,每个线程都能得到正确结果;同时在一个线程内支持线程切换,无论被切换多少次,结果都是正确的。


公平锁

使用 ReentrantLock 的时候,你会发现 ReentrantLock 这个类有两个构造函数,一个是无参构造函数,一个是传入 fair 参数的构造函数。fair 参数代表的是锁的公平策略,如果传入 true 就表示需要构造一个公平锁,反之则表示要构造一个非公平锁。


//无参构造函数:默认非公平锁
public ReentrantLock() {
    sync = new NonfairSync();
}
//根据公平策略参数创建锁
public ReentrantLock(boolean fair){
    sync = fair ? new FairSync() 
                : new NonfairSync();
}

生产者消费者

面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法,能够支持2个生产者线程以及10个消费者线程的阻塞调用,使用Lock和Condition来实现。

/**
 * 面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法,
 * 能够支持2个生产者线程以及10个消费者线程的阻塞调用
 * 使用Lock和Condition来实现
 * @author chendawei
 */
package JUC.Interview;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyContainer2<T> {
    final private LinkedList<T> lists = new LinkedList<>();
    final private int MAX = 10; //最多10个元素
    private int count = 0;
    private Lock lock = new ReentrantLock();
    private Condition producer = lock.newCondition();
    private Condition consumer = lock.newCondition();

    public void put(T t) {
        try {
            lock.lock();
            while(lists.size() == MAX) { //想想为什么用while而不是用if?
                producer.await();
            }

            lists.add(t);
            ++count;
            consumer.signalAll(); //通知消费者线程进行消费
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public T get() {
        T t = null;
        try {
            lock.lock();
            while(lists.size() == 0) {
                consumer.await();
            }
            t = lists.removeFirst();
            count --;
            producer.signalAll(); //通知生产者进行生产
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return t;
    }

    public static void main(String[] args) {
        MyContainer2<String> c = new MyContainer2<>();
        //启动消费者线程
        for(int i=0; i<10; i++) {
            new Thread(()->{
                for(int j=0; j<5; j++) System.out.println(c.get());
            }, "c" + i).start();
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //启动生产者线程
        for(int i=0; i<2; i++) {
            new Thread(()->{
                for(int j=0; j<25; j++) c.put(Thread.currentThread().getName() + " " + j);
            }, "p" + i).start();
        }
    }
}

基于yolo11的BGA图像目标检测 15.YOLOv8的n/s版本(如YOLOv8n-1280),或通过TensorRT量化压缩模型。3.使用自适应batch_size(如根据GPU显存动态调整),推荐16-32。为采集分辨率整数倍(如原图2592×1944,训练时缩放为640×480),保持宽高比。14.采用余弦退火学习率(cos_lr)和早停(patience=50),防止过拟合。1.模型标注后,少量标注全部人工校验,大量数据抽检,部分人工检验。13.部署模型后持续收集困难样本(如模棱两可的预测结果),定期迭代更新模型。 阅读详情

相关推荐

NVIDIA Jetson Orin DLA架构解析与AI推理优化实践

深度学习加速器(DLA)作为专用AI推理芯片,通过固定功能架构实现卷积、池化等神经网络操作的高效能比处理。其核心原理在于硬件级优化计算单元与数据流,相比通用GPU可提升3-5倍能效。在边缘计算场景中,DLA与GPU的异构协同成为关键,特别适合自动驾驶感知、机器人视觉等实时性要求高的应用。NVIDIA Jetson Orin平台通过结构化稀疏技术,在ResNet50等模型上实现近2倍性能提升。开发实践中需注意算子支持、精度校准等关键点,结合TensorRT工具链可充分发挥DLA在低功耗场景的独特优势。

weixin_32999557的博客 397

Lock中的Condition

参考:https://segmentfault.com/a/1190000014419022?utm_source=index-hottest#item-1-2 synchronized关键字与wait()和notify/notifyAll()方法相结合可以实现等待/通知机制,ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition() 方法 ...

Q酱的专栏 781

Windowns下Git环境配置-命令行方式

文章目录一、配置Git1.1 下载Git并安装1.2 配置本地Git用户名和邮箱1.3 注册GitHub二、生成本地公钥,放到GitHub上-SSH Key2.1 生成本地公钥命令2.2 查看生成的公钥2.3 在GitHub放上公钥并测试连通性三、创建项目实操四、可能出现的问题4.1.push不成功4.2.提示SSL的问题4.3.域名不能解析的问题4.4.如果github连接不上的问题 一、配置Git 1.1 下载Git并安装 Git官网 默认安装,根据需要修改安装路径 1.2 配置本地Git用户名和邮箱

学习工作笔记 1135

Lock的Condition使用

Lock是java 1.5中引入的线程同步工具,它主要用于多线程下共享资源的控制。 Condition 本质是一个接口,它包含如下方法 // 让线程进入等通知待状态 void await() throws InterruptedException; void awaitUninterruptibly(); //让线程进入等待通知状态,超时结束等待状态,并抛出异常 lon

2706

告别抓瞎!手把手教你用Keysight Infinium和M8040完成PCIe 5.0 TX/RX信号完整性测试

本文详细介绍了如何使用Keysight Infinium示波器和M8040误码仪完成PCIe 5.0 TX/RX信号完整性测试。从测试前的设备准备、软件配置到具体的TX信号测试步骤和RX容限测试实战,提供了全面的操作指南和常见问题解决方案,帮助工程师高效完成PCIe 5.0合规性测试。

weixin_30911451的博客 503

[学习笔记]Esp32 + 4G模块,随身wifi,ppp拨号上网

Esp32S3 + 4G模块制作随身WIFI教程

weixin_45595548的博客 7413

线程系列(四)--浅说高层并发

高层并发

xiong_hui_hui的博客 649

Versal ACAP NoC实战:像理解计算机网络一样配置AXI NoC,打通PS与PL数据通路

本文深入探讨了Versal ACAP NoC的配置与优化,通过计算机网络类比解析NoC架构,详细介绍了在VD100开发板上配置AXI NoC实现PS与PL数据交互的实战步骤。文章涵盖NoC组件功能、Vivado配置技巧、性能优化方法及常见问题解决方案,帮助开发者高效打通Versal芯片的数据通路。

weixin_42665255的博客 291

【工具类】基于Redis的分布式可重入锁(Java)

基于Redis的可重入锁,这个版本通过spring注入方式完成的Service版本,有时间写一个Util的版本。 1.定义的Lock接口,与JDK内置的类似,添加了过期时间,没有支持Condition。 import java.util.concurrent.TimeUnit; /** * @author : wudi28 * @date : 2018/9/24 18:35 */ ...

adiaixin123456的专栏 2555

手把手教你用RK3568开发板实现FPGA与Linux的DMA通信(含完整代码解析)

本文详细介绍了如何在RK3568开发板上实现FPGA与Linux系统的DMA通信,包括硬件配置、软件环境搭建、DMA通信原理、驱动开发及性能优化。通过完整的代码解析和实战案例,帮助开发者快速掌握异构系统间的高效数据传输技术,适用于物联网和边缘计算等场景。

weixin_29174385的博客 201

微信小程序 - 真机调试调用接口报错{errno: 600001, errMsg: “request:fail -102:net::ERR_CONNECTION_REFUSED},真机运行测试请求异常

微信小程序,真机,调试测试,运行报错,API接口,服务器接口都报错了,小程序报错errno: 600001,小程序报错request:fail -102:net::ERR_CONNECTION_REFUSED,真实手机打开接口全都失效了,微信小程序真机测试失败,微信小程序{errno: 600001, errMsg: "request:fail -102:net::ERR_CONNECTION_REFUSED"},详细解决方法,https,服务器SSL证书,无法解决,服务器更换SSL证书,接口地址改了也不行

🏆 前端领域优质创作者 1万+

Lock锁、ReentrantLock(可重入锁)使用

Lock锁、ReentrantLock可重入锁使用Lock锁ReentrantLock(可重入锁)使用 Lock锁 jdk 5.0开始,Java提供了更强大的线程同步机制,可以显示定义同步锁对象来实现同步。同步锁使用Lock对象充当。 java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前需要先获得Lock对象。 ReentrantLock(可重入锁)类

郝开的博客 686

金融行业大数据可视化:实时监控与风险预警系统构建

随着金融业务数字化转型,日均产生的交易数据、市场数据、客户行为数据呈指数级增长(单家银行日交易数据量可达TB级)。数据实时性不足(分钟级延迟难以应对高频交易风险)风险特征挖掘浅层(仅基于规则引擎,漏报率高达30%+)可视化分析能力薄弱(静态报表无法支持动态决策)本文聚焦构建具备毫秒级数据响应智能风险建模交互式可视化决策能力的新一代系统,覆盖数据采集、实时处理、多维可视化、智能预警四大核心模块,适用于银行、证券、保险等金融细分领域。章节核心内容技术亮点核心概念可视化系统架构/数据流模型。

AI天才研究院 1522

并发编程(四)

ThreadLocal AQS和JUC ReentranLock重入锁 Lock lockInterruptibly TryLock 公平锁和非公平锁 Condition重入锁搭配类 常用方法 Semaphore ReadWriteLock CyclicBarrier LockSupport线程阻塞工具类

qq_41686437的博客 245

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

visio安装包

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

Lock锁与Condition详解

目录引子重新认识Lock接口你了解Condition接口吗Condition接口与示例Condition如何实现 引子 三个线程分别打印A、B、C,要求按ABC的顺序循环打印10次。 ReentrantLock和Conditon实现 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; pub

7me 6717

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

自学并发编程之:Lock与Condition

可重入锁”是指当一个线程调用 object.lock()获取到锁,进入临界区后,再次调用object.lock(),仍然可以获取到该锁。显然,通常的锁都要设计成可重入的,否则就会发生死锁。synchronized关键字,就是可重入锁。在一个synchronized方法method1()里面调用另外一个synchronized方法method2()。如果synchronized关键字不可重入,那么在method2()处就会发生阻塞,这显然不可行。

2401_83384536的博客 1341

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【Java并发】揭秘Lock体系 -- condition等待通知机制

Java并发 -- condition等待通知机制

2403_87459748的博客 1548

【Lock中的Condition分析】

在 Java 中,Lock 和 Condition 是并发编程中用于实现线程同步的重要工具,它们提供了比传统 synchronized 更灵活的线程控制能力。Lock 提供了显式的锁操作,而 Condition 则允许线程在某些条件不满足时挂起,并在条件满足时被唤醒。以下是一个使用 Lock 和 Condition 实现生产者-消费者模型的示例代码。这个示例展示了如何通过 Lock 和 Condition 来协调生产者和消费者的行为。

weixin_47068446的博客 1274

Java并发包中的管程:Lock和Condition

指的是线程可以重复获取同一把锁。

2301_81948543的博客 1153

Java 并发编程:使用 Lock 和 Condition 实现线程同步

Lock和Condition接口是 Java 并发编程中非常重要的工具,它们为开发者提供了比synchronized更灵活、更强大的同步机制。通过合理使用Lock和Condition,可以实现复杂的同步控制、高效的线程间通信,从而提升程序的性能和稳定性。在实际开发中,应根据具体的业务场景和需求,选择合适的同步方式。同时,在使用Lock和Condition时,要注意正确地获取和释放锁,避免出现死锁等问题。随着 Java 版本的不断更新,并发编程的工具和技术也在不断发展和完善。

数字魔方操控师的博客 1149

java并发---lock和condition

一、 java.util.concurrent.locks下面接口介绍          java.util.concurrent.locks包为锁和等待条件提供一个框架的接口和类,它不同于内置同步(synchronize)和监视器。该框架允许更灵活地使用lock和condition,但以更难用的语法为代价。 它下面有三个接口:Lock , ReadtrantLock , Conditio

冰雪的专栏 5482

并发工具类:用Condition实现等待通知

在 Java Concurrent 包中,AQS(AbstractQueuedSynchronizer) 是整个并发工具包的核心。而 Condition(通常以 ConditionObject 的形式实现在 AQS 内部)则是用来替代传统 Java Object.wait()/notify() 的线程间通信机制特性传统 Object 方法 (wait/notify)底层队列每个 Object 只有一个 JVM 内部的 WaitSet每个 Condition 对象都有一个独立的单向链表队列条件数量。

小识的博客 2861

理解Java并发编程:Java Lock中的Condition条件使用

Java Lock中的Condition条件

鸟哥哥的专栏 4078

【Java并发编程】Lock与Condition接口

Lock与Condition接口 一. 介绍 我在《AQS(5)——ConditionObject》这篇文章中曾提过管程这个概念,它能够解决并发编程领域的两大核心问题 互斥:同一时刻只能有一个线程访问共享资源 同步:线程之间的通信协作 而Java在1.5版本之前,是通过synchronized来实现。到了Java 1.5版本,Java大神Doug Lea的又在Java并发包增加了Lock和Condition两接口来解决这两个问题 为啥synchronized实现了管程,还要添加这两接口重复实现呢?答案很

哈喽羊 588

掌握Java并发编程:Lock、Condition与并发集合

Condition可以和Lock一起使用,用于管理线程的等待和唤醒操作,可以将线程的等待和唤醒操作细粒度地控制在特定的条件下。它们提供了更灵活和可扩展的方式来处理多线程编程中的问题,同时还提供了更高效和线程安全的数据结构和容器。为了正确地处理并发问题,需要一些并发编程相关的基础知识,掌握和熟练应用Java提供的并发编程相关的工具和类是必要的。通过使用Condition,可以实现更加灵活和高效的线程通信方式,避免了传统的使用Object的wait()和notify()所带来的一些限制和问题。

naer_chongya的博客 814

Java并发---synchronized、Lock、Condition的区别

讲述Java并发锁的区别和使用方法

brycegao321的博客 2813
上一篇: (二)SpringBoot启动流程(概括)
下一篇: (二)并发工具类CountDownLatch(门闩)与CyclicBarrier(栅栏)
香草星冰乐
博客等级 码龄7年 21粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值