JavaSE-多线程(2.2)- 锁举例2(Reentrant Lock )

SpringBoot+Vue+MySQL 高校学科竞赛平台 完整可运行版(源码+文档) 本项目基于SpringBoot+Vue+MySQL构建高校学科竞赛管理平台,覆盖学生、教师、领队教师、管理员四大角色,实现竞赛发布、报名、刷题、评分、公示等全流程闭环管理。系统架构清晰,技术主流,配套完整源码、数据库脚本、万字论文、开题报告、答辩PPT及部署文档,支持一键运行,适用于毕业设计、课程设计及院系二次开发,真正实现“开箱即用”。 阅读详情

JavaSE-多线程(2.2)- 锁举例2(Reentrant Lock )

Reentrant Lock 基于CAS

package com.hs.example.base.multithread.day01;

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

/**
 * 自定义容器,固定容量最大值为MAX_COUNT,运行多线程并发put和get
 *
 * @param <T>
 */
public class ReentrantLock4<T> {

    private Lock lock = new ReentrantLock();
    //first-in-first-out (FIFO) wait queues.先进先出队列
    private Condition producer = lock.newCondition();
    private Condition consumer = lock.newCondition();

    final LinkedList<T> lists = new LinkedList<>();
    final int MAX_COUNT = 10;
    private int count = 0;

    /**
     * 加锁,防止count与实际lists大小不一致
     *
     * @param t
     */
    public void put(T t) {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " put start...");
            /**
             * 这里为什么不能用if,因为当前线程在等待时,其他线程也有机会执行put使得list.size发生改变,所以需要继续执行 == MAX_COUNT的判断
             */
            while (lists.size() == MAX_COUNT) {
                try {
                    System.out.println(Thread.currentThread().getName() + " waiting...");
                    producer.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            lists.add(t);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
            //可以选择只唤醒消费者
            consumer.signalAll();
            System.out.println(Thread.currentThread().getName() + " put end...");
        } finally {
            lock.unlock();
        }
    }

    public synchronized T get() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " get start...");
            T t = null;
            while (lists.size() == 0) {
                try {
                    consumer.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            t = lists.removeFirst();
            count--;
            producer.signalAll();
            System.out.println(Thread.currentThread().getName() + " get end...");
            return t;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ReentrantLock4 reentrantLock4 = new ReentrantLock4();
        for (int i = 0; i < 20; i++) {
            Thread t = new Thread(() -> {
                reentrantLock4.put("str");
            }, "put thread" + i);
            t.start();
        }

        for (int i = 0; i < 20; i++) {
            Thread t = new Thread(() -> {
                reentrantLock4.get();
            }, "get thread" + i);
            t.start();
        }
    }
}
put thread0 put start...
put thread0 put end...
put thread2 put start...
put thread2 put end...
put thread3 put start...
put thread3 put end...
put thread6 put start...
put thread6 put end...
put thread7 put start...
put thread7 put end...
put thread10 put start...
put thread10 put end...
put thread11 put start...
put thread11 put end...
get thread7 get start...
get thread7 get end...
put thread4 put start...
put thread4 put end...
put thread5 put start...
put thread5 put end...
put thread9 put start...
put thread9 put end...
put thread8 put start...
put thread8 put end...
put thread12 put start...
put thread12 waiting...
put thread13 put start...
put thread13 waiting...
put thread16 put start...
put thread16 waiting...
put thread17 put start...
put thread17 waiting...
put thread14 put start...
put thread14 waiting...
put thread15 put start...
put thread15 waiting...
put thread19 put start...
put thread19 waiting...
put thread18 put start...
put thread18 waiting...
put thread1 put start...
put thread1 waiting...
get thread17 get start...
get thread17 get end...
get thread16 get start...
get thread16 get end...
put thread12 put end...
put thread13 put end...
put thread16 waiting...
put thread17 waiting...
put thread14 waiting...
put thread15 waiting...
put thread19 waiting...
put thread18 waiting...
put thread1 waiting...
get thread18 get start...
get thread18 get end...
put thread16 put end...
put thread17 waiting...
put thread14 waiting...
put thread15 waiting...
put thread19 waiting...
put thread18 waiting...
put thread1 waiting...
get thread15 get start...
get thread15 get end...
put thread17 put end...
put thread14 waiting...
put thread15 waiting...
put thread19 waiting...
put thread18 waiting...
put thread1 waiting...
get thread19 get start...
get thread19 get end...
put thread14 put end...
put thread15 waiting...
put thread19 waiting...
put thread18 waiting...
put thread1 waiting...
get thread14 get start...
get thread14 get end...
put thread15 put end...
put thread19 waiting...
put thread18 waiting...
put thread1 waiting...
get thread11 get start...
get thread11 get end...
put thread19 put end...
put thread18 waiting...
put thread1 waiting...
get thread10 get start...
get thread10 get end...
put thread18 put end...
put thread1 waiting...
get thread6 get start...
get thread6 get end...
get thread3 get start...
get thread3 get end...
put thread1 put end...
get thread2 get start...
get thread2 get end...
get thread13 get start...
get thread13 get end...
get thread12 get start...
get thread12 get end...
get thread9 get start...
get thread9 get end...
get thread8 get start...
get thread8 get end...
get thread5 get start...
get thread5 get end...
get thread4 get start...
get thread4 get end...
get thread1 get start...
get thread1 get end...
get thread0 get start...
get thread0 get end...
SRAM compiler选项中 Soft Error Repair (SER) 引起的瞬时故障,可能会影响 SRAM 中存储的数据。SER 功能通过某种机制检测并修复这些错误,从而提高存储器的可靠性。在 SRAM 编译器中, 阅读详情

相关推荐

中国ETF基金行情数据API接口

上交所:https://tsanghi.com/api/fin/etf/XSHG/daily?token={token}&ticker={ticker} 深交所:https://tsanghi.com/api/fin/etf/XSHE/daily?token={token}&ticker={ticker}

2401_83242712的博客 4035

JavaSE-多线程(5)- Reentrant Lock (可重入锁)1

JavaSE-多线程(5)- Reentrant Lock (可重入锁1) 简单解释 线程A 在执行加锁方法 m 时获得锁 L,如果在m方法中调用的 方法 n 同时需要获得锁 L,那么不会出现互斥现象,即同一线程可重入同一锁对象 不同线程之间无法重入锁 例1 下例中,m1方法每隔1秒打印一次i值,共打印10次,m2方法直接输出一段文字,t1线程调用ReentrantLock1对象m1方法,主线程 睡眠 1秒后 t2 线程启动调用 ReentrantLock1 对象m2方法,由打印结果可知,t2线程在t1线程

sql2008help的博客 202

手把手带你搞懂电压跌落测试DIP

砖一用4分钟时间手把手带你搞懂电压跌落测试DIP,希望对你有用~

qq_45508321的博客 7920

ReentrantLock 源码分析

ReentrantLock 源码分析简介Lock接口提供的功能公平锁和非公平锁公平锁非公平锁公平锁和非公平锁性能对比 简介 ReentrantLock是Java SE 5新增的jdk层面实现可重入锁的功能, 提供了与synchronized类似的同步功能,只是在使用时需要显示的获取和释放锁。虽然缺少了隐私获取和释放锁的便捷性,但是缺拥有了锁获取和释放的可操作性、可中断的获取锁以及超时获取锁等多种s...

等风 576

SOC设计必看!Tessent DRC检查中最容易踩的5个坑(附解决方案)

本文针对SOC设计中Tessent DRC检查的常见问题,详细分析了5个最易忽视的陷阱,包括时钟域交叉、扫描链虚连、多电压域规则等,并提供专业解决方案。特别针对芯片设计中的DFT验证难点,分享了经过验证的调试方法和Tessent工具使用技巧,帮助工程师提升DRC检查效率。

weixin_29280657的博客 496

Kylin-Desktop-V10-SP1海光版虚拟机安装全流程(含桥接网络配置)

本文详细介绍了在VMware虚拟机中安装Kylin-Desktop-V10-SP1海光版操作系统的完整流程,重点解决了基于海光(Hygon C86)平台的网络配置难题。内容涵盖从镜像准备、虚拟机创建、系统安装到桥接网络配置的三种实战方法,并提供了安装后的优化与必备软件配置指南,帮助用户高效搭建国产化测试与开发环境。

weixin_29323493的博客 355

大数据成神之路-Java高级特性增强(Synchronized关键字)

Java高级特性增强-Synchronized 本部分网络上有大量的资源可以参考,在这里做了部分整理,感谢前辈的付出,每节文章末尾有引用列表,源码推荐看JDK1.8以后的版本,注意甄别~ ####多线程 ###集合框架 ###NIO ###Java并发容器 Synchronized关键字 简介 Java并发编程这个领域中synchronized关键字一直都是元老级的角色,很久之前很多人都会称它为...

微信搜:import_bigdata,大数据领域硬核原创作者 404

Jetson 平台编译安装 FFmpeg 7.1(支持 Nvmpi + SRT + x265)

摘要: 本文详细介绍了在NVIDIA Jetson平台上编译FFmpeg 7.1并集成关键功能的全过程。通过补丁方式加入Nvmpi实现硬件加速支持,同时编译集成x265编码器和SRT低延迟传输协议。步骤涵盖:1)安装x265编码器;2)配置SRT协议支持;3)编译jetson-ffmpeg的Nvmpi接口;4)定制化编译FFmpeg 7.1;5)验证模块集成情况。最终实现支持硬件编解码、高效HEVC压缩和可靠推流的增强版FFmpeg,为Jetson平台的音视频处理提供完整解决方案。

J。 345

Java Thread Pools — Deep Dive

Java线程池核心原理摘要 线程池作用:解决线程创建开销大、资源耗尽问题,通过复用固定线程、控制并发量、任务队列解耦任务提交与执行。Java提供Executor框架(Java 5+)实现。 核心类层次: Executor → ExecutorService → ThreadPoolExecutor(核心)/ScheduledThreadPoolExecutor(定时) ForkJoinPool:工作窃取,支持并行流和CompletableFuture ThreadPoolExecutor关键参数: core

quwenqian的专栏 389

Django 6.0:有哪些新特性以及它们对实际项目的重要性

Django 6.0 感觉像是一个成熟的版本,它基于实际应用案例而打造。它减少了不必要的复杂性,同时扩展了框架的开箱即用功能。升级到 Django 6.0 不仅仅是为了保持版本更新,更是为了构建更易于维护、更安全、更能适应未来发展的应用程序。

iCloudEnd的博客 341

解决 maven编译项目-Fatal error compiling: 无效的目标发行版: 21 -> [Help 1]

惊奇的发现,maven没有用环境变量中设置好的JAVA_HOME目录,至此发现错误原因,原来执行java -version默认使用系统环境变量JAVA_HOME,而maven优先使用了windows的用户变量JAVA_HOME(这里之前忘记修改,仍然指向java8路径),修改用户变量JAVA_HOME指向java21或删除该用户变量JAVA_HOME(如无它用)后即可。打开maven包所在的目录,在maven的配置文件 mvn.cmd 文件中,设置java_home的目录。

litlit023的专栏 1800

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 293

VSCode + QMT 量化交易完整解决方案!

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1327

信创环境下PageOffice文档控件适配与实践

信创适配做到文档控件这一层,拼的已经不是"有没有国产版本",而是同一个功能在两类终端上是否真的等价。等价的标准很具体:同一次点击能得到同样的结果,同一份公文能得到同样的版式,同一个项目不需要维护两套代码。这背后是三件并不轻松的工作:服务端用一套接口同时支撑两类终端,客户端把两种系统与四种芯片的安装包分发清楚,文档内核层由产品侧跟着 WPS 的版本走。浏览器这一层的压力,则被收进了产品自己的窗口里——升级节奏由产品掌握,不再交给运气。

zi_wu_xian的专栏 320

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 350

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

第三篇 第 6 课

前置:第三篇第 1 课(stdx 引入),第二篇第 1 课(std.regex)。环境:仓颉 SDK 1.2.0。本文所有代码与输出均逐行实测。

weixin_41618057的博客 506

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

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

【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端

上一篇讲了 MCP 的概念:标准协议、三大角色、M+N 替代 M×N。

nice_lcj520的博客 521

Java 集合容器高频面试题全解:HashMap 树化阈值、1.7 死循环与 ConcurrentHashMap 演进(2026 招聘 JD 真题复盘)

HashMap 树化阈值 8 的泊松分布依据、退化阈值 6 的防抖设计、JDK 1.7 头插成环死循环的排查与修复、1.8 尾插后为何仍线程不安全、ConcurrentHashMap 放弃分段锁的原因与 ForwardingNode 协作扩容、computeIfAbsent 死锁陷阱、大集合找重复的场景题选型,附三层追问链自测。题目来源为 38 期公开招聘 JD 样本与字节、拼多多、建行、美团、快手公开面经。

蒙眼过河 414

spdlog 同步日志库使用详解

spdlog是一个轻量级 C++ 日志库,支持同步日志、异步日志、多线程日志、日志文件轮转和自定义日志格式。对于嵌入式 Linux 应用开发,我建议先使用。它可以帮我们完成:日志级别过滤。时间戳和线程 ID 输出。日志格式化。终端和文件输出。多线程安全写入。日志文件按大小或时间轮转。我们不需要自己实现互斥锁、文件写入、日志格式化和轮转等底层功能。

zengjiajun2006的博客 995

JavaEE通关手册:数据类型与变量

代码无需额外处理,编译时编译器自动完成转换。

xys_678的博客 77

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 367

IDEA 简介:从零认识 IntelliJ IDEA

IDEA 全称,是由 JetBrains 公司开发的一款主流 Java 集成开发环境(IDE)。它集代码编辑、编译、调试、测试、版本控制、构建管理等功能于一体,被大量 Java 开发者视为日常开发的首选工具。所谓 IDE(Integrated Development Environment,集成开发环境),就是把写代码所需的各类工具整合到同一个界面中。相比只用文本编辑器加命令行编译,IDE 能显著减少重复操作,让开发者把精力集中在业务逻辑上。

ztI10的博客 166

Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

【代码】Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

m0_64476639的博客 338

c++ explicit关键字详解

explicit。

拒绝AI文,努力在AI时代写出感动人心的好文章 45

ubuntu安装hadoop系统

本文详细介绍了基于VMware克隆虚拟机搭建三节点Hadoop分布式集群的全过程:使用同一Ubuntu镜像克隆出master、worker1、worker2三台虚拟机,依次配置主机名、固定IP(如192.168.82.10/11/12)、SSH服务及免密登录,确保节点间网络互通。随后安装Java,下载配置Hadoop并分发至各节点,最终初始化启动集群,验证其存储与计算功能,实现高效的大数据环境部署。

qq_43592674的博客 348

TRingBuffer两端都能增删(快递站版)

TRingBuffer 是一个支持两端增删、下标访问且容量动态增长的环形双端队列。它通过无符号索引的永不归零设计,利用减法自动模运算实现空满判断与元素计数,避免了传统环形缓冲浪费格子的问题。内部以票号(索引)标记首尾,扩容时重排元素为连续存储,保证 O(1) 操作与高缓存效率。虽不线程安全,但其高效性使其成为游戏开发中事件队列、命令缓冲等场景的理想选择。

u013768914的博客 301
上一篇: JavaSE-多线程(2.1)- 锁举例1(synchronized)
下一篇: Nacos(1.1)- nacos 使用
sql2008help
博客等级 码龄11年 80粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值