当前位置: 首页 > article >正文

八股整理之JUC篇

怎么保证多线程安全synchronized关键字:可以使用synchronized关键字来同步代码块或方法确保同一时刻只有一个线程可以访问这些代码。对象锁是通过synchronized关键字锁定对象的监视器(monitor来实现的。volatile关键字volatile关键字用于变量确保所有线程看到的是该变量的最新值而不是可能存储在本地寄存器中的副本。Lock接口和ReentrantLock类java.util.concurrent.locks.Lock接口提供了比synchronized更强大的锁定机制ReentrantLock是一个实现该接口的例子提供了更灵活的锁管理和更高的性能。原子类Java并发库java.util.concurrent.atomic提供了原子类如AtomicInteger、AtomicLong等这些类提供了原子操作可以用于更新基本类型的变量而无需额外的同步。线程局部变量ThreadLocal类可以为每个线程提供独立的变量副本这样每个线程都拥有自己的变量消除了竞争条件。并发集合:使用java.util.concurrent包中的线程安全集合如ConcurrentHashMap、ConcurrentLinkedQueue等这些集合内部已经实现了线程安全的逻辑。JUC工具类: 使用java.util.concurrent包中的一些工具类可以用于控制线程间的同步和协作。例如Semaphore和CyclicBarrier等。Java中有哪些常用的锁在什么场景下使用内置锁synchronized、ReentrantLock、读写锁ReadWriteLock、乐观锁和悲观锁、自旋锁synchronized 工作原理synchronized是Java提供的原子性内置锁这种内置的并且使用者看不到的锁也被称为监视器锁使用synchronized之后会在编译之后在同步的代码块前后加上monitorenter和monitorexit字节码指令他依赖操作系统底层互斥锁实现。他的作用主要就是实现原子性操作和解决共享变量的内存可见性问题。执行monitorenter指令时会尝试获取对象锁如果对象没有被锁定或者已经获得了锁锁的计数器1。此时其他竞争锁的线程则会进入等待队列中。执行monitorexit指令时则会把计数器-1当计数器值为0时则锁释放处于等待队列中的线程再继续竞争锁。synchronized是排它锁当一个线程获得锁之后其他线程必须等待该线程释放锁后才能获得锁而且由于Java中的线程和操作系统原生线程是一一对应的线程被阻塞或者唤醒时时会从用户态切换到内核态这种转换非常消耗性能。从内存语义来说加锁的过程会清除工作内存中的共享变量再从主内存读取而释放锁的过程则是将工作内存中的共享变量写回主内存。实际上大部分时候我认为说到monitorenter就行了但是为了更清楚的描述还是再具体一点。除了用synchronized还有什么方法可以实现线程同步使用ReentrantLock类、使用volatile关键字、使用Atomic类synchronized锁静态方法和普通方法区别锁的对象不同普通方法锁的是当前对象实例this。同一对象实例的synchronized普通方法同一时间只能被一个线程访问不同对象实例间互不影响可被不同线程同时访问各自的同步普通方法。静态方法锁的是当前类的class对象。由于类的class对象全局唯一无论多少个对象实例该静态同步方法同一时间只能被一个线程访问。作用范围不同普通方法仅对同一对象实例的同步方法调用互斥不同对象实例的同步普通方法可并行执行。静态方法对整个类的所有实例的该静态方法调用都互斥一个线程进入静态同步方法其他线程无法进入同一类任何实例的该方法。多实例场景影响不同普通方法多线程访问不同对象实例的同步普通方法时可同时执行。静态方法不管有多少对象实例同一时间仅一个线程能执行该静态同步方法。synchronized锁升级的过程讲一下快手一面整个升级路径是无锁→偏向锁→轻量级锁→重量级锁这是一个单向过程只能升级不能降级。这个机制的核心在于对象头中的MarkWord它会根据锁状态存储不同的信息通过其中的锁标志位来标识当前锁处于什么状态。首先是无锁状态。对象刚创建出来时没有任何线程访问此时MarkWord中存储的是对象的HashCode、分代年龄等信息锁标志位是01偏向标志位是0。这是对象的初始状态还没有涉及任何同步操作。需要注意的是一旦对象调用过hashCode方法它就无法进入偏向锁状态了因为偏向锁需要用MarkWord的空间来存储线程ID而hashCode也要占用这部分空间两者冲突。当第一个线程进入同步块时锁会升级到偏向锁。此时会通过CAS操作在对象头的MarkWord中记录该线程ID锁标志位保持01但偏向标志位变为1。之后这个线程再次进入同步块时只需简单判断MarkWord中的线程ID是否是自己如果是就直接进入完全不需要加锁解锁操作这就极大优化了单线程反复进入同步块的场景。但一旦有第二个线程尝试获取这个锁就说明出现了竞争偏向锁就会被撤销。撤销过程需要等到安全点暂停持有偏向锁的线程检查该线程是否还在执行同步代码然后清除偏向标记这个过程开销不小。撤销偏向锁后就进入轻量级锁阶段。这时JVM会在当前线程的栈帧中创建锁记录空间把对象头的MarkWord复制进去然后通过CAS操作尝试把对象头的MarkWord更新为指向锁记录的指针锁标志位变为00。如果CAS成功说明获取轻量级锁成功。如果失败说明有其他线程在竞争这时线程会进行自旋不断重试CAS操作期望在短时间内持有锁的线程能释放锁。自旋的本质是用CPU时间换取避免线程阻塞的开销所以只适合锁持有时间很短的场景。重量级锁就是传统的synchronized实现它依赖操作系统的互斥量Mutex来实现锁标志位变为10Mark Word指向Monitor对象。未获取锁的线程会被阻塞进入Monitor的等待队列这个过程需要从用户态切换到内核态由操作系统来调度线程的阻塞和唤醒开销非常大。但在竞争激烈、持锁时间长的场景下阻塞线程反而比自旋更节省CPU资源这就是为什么要升级为重量级锁。用空间换时间用复杂度换性能在JDK 15下synchronized 的实际升级路径已经简化为无锁 → 轻量级锁 → 重量级锁废弃偏向锁的主要原因是它让 JVM 实现过于复杂而现代应用尤其是 lambda、record、虚拟线程大行其道的场景很少再从偏向锁中获益。CAS 和 AQS 有什么关系CAS 和 AQS 两者的区别CAS是一种乐观锁机制它包含三个操作数内存位置V)、预期值A和新值B)。CAS操作的逻辑是如果内存位置的值等于预期值A则将其更新为新值B否则不做任何操作。整个过程是原子性的通常由硬件指令支持如在现代处理器上cmpxchg指令可以实现CAS 操作。AQS 是一个用于构建锁和同步器的框架许多同步器如ReentrantLock、Semaphore、CountDownLatch等都是基于 AQS 构建的。AQS 使用一个volatile的整数变量state来表示同步状态通过内置的FIFo队列来管理等待线程。它提供了一些基本的操作如acquire获取资源和release(释放资源)这些操作会修改state的值并根据state的值来判断线程是否可以获取或释放资源。AQS 的acquire操作通常会先尝试获取资源如果失败线程将被添加到等待队列中并阻塞等待。release操作会释放资源并唤醒等待队列中的线程。CAS 和 AQS 两者的联系CAS 为 AQS 提供原子操作支持Threadlocal作用原理具体里面存的key value是啥会有什么问题如何解决?ThreadLocal是Java中用于解决线程安全问题的一种机制它允许创建线程局部变量即每个线程都有自己独立的变量副本从而避免了线程间的资源共享和同步问题。ThreadLocal作用线程隔离ThreadLocal为每个线程提供了独立的变量副本这意味着线程之间不会相互影响可以安全地在多线程环境中使用这些变量而不必担心数据竞争或同步问题。降低耦合度在同一个线程内的多个函数或组件之间使用ThreadLocal可以减少参数的传递降低代码之间的耦合度使代码更加清晰和模块化。性能优势由于ThreadLocal避免了线程间的同步开销所以在大量线程并发执行时相比传统的锁机制它可以提供更好的性能。Java中想实现一个乐观锁都有哪些方式1、CASCompare and Swap操作2、版本号控制增加一个版本号字段记录数据更新时候的版本每次更新时递增版本号。在更新数据时同时比较版本号若当前版本号和更新前获取的版本号一致则更新成功否则失败。3、时间戳CAS 有什么缺点1、ABA问题ABA的问题指的是在CAS更新的过程中当读取到的值是A然后准备赋值的时候仍然是A但是实际上有可能A的值被改成了B然后又被改回了A这个CAS更新的漏洞就叫做ABA。只是ABA的问题大部分场景下都不影响并发的最终效果。Java中有AtomicStampedReference来解决这个问题他加入了预期标志和更新后标志两个字段更新时不光检查值还要检查当前的标志是否等于预期标志全部相等的话才会更新。就是新加一个版本号验证2、循环时间长开销大自旋CAS的方式如果长时间不成功会给CPU带来很大的开销。3、只能保证一个共享变量的原子操作只对一个共享变量操作可以保证原子性但是多个则不行多个可以通过AtomicReference来处理或者使用锁synchronized实现。为什么不能所有的锁都用CASCAS操作是基于循环重试的机制如果CAS操作一直未能成功线程会一直自旋重试占用CPU资源。在高并发情况下大量线程自旋会导致CPU资源浪费。volatile和sychronized比较Synchronized解决了多线程访问共享资源时可能出现的竞态条件和数据不一致的问题保证了线程安全性。Volatile解决了变量在多线程环境下的可见性和有序性问题确保了变量的修改对其他线程是可见的。Synchronized: Synchronized是一种排他性的同步机制保证了多个线程访问共享资源时的互斥性即同一时刻只允许一个线程访问共享资源。通过对代码块或方法添加Synchronized关键字来实现同步。Volatile:Volatile是一种轻量级的同步机制用来保证变量的可见性和禁止指令重排序。当一个变量被声明为Volatile时线程在读取该变量时会直接从内存中读取而不会使用缓存同时对该变量的写操作会立即刷回主内存而不是缓存在本地内存中。非公平锁吞吐量为什么比公平锁大公平锁在整个执行过程中线程会从运行状态切换到休眠状态再从休眠状态恢复成运行状态但线程每次休眠和恢复都需要从用户态转换成内核态而这个状态的转换是比较慢的所以公平锁的执行速度会比较慢。非公平锁获取锁不用遵循先到先得的规则从而避免了线程休眠和恢复的操作这样就加速了程序的执行效率。线程池拒绝策略除了默认的 AbortPolicy直接抛异常还有 CallerRunsPolicy让提交任务的主线程自己执行缓解压力、DiscardPolicy直接静默丢弃新任务、DiscardOldestPolicy丢弃队列里最旧的任务再提交新任务有线程池参数设置的经验吗核心线程数corePoolSize设置的经验CPU密集型corePoolSize CPU核数 1避免过多线程竞争CPUIO密集型corePoolSize CPU核数 x 2或更高具体看IO等待时间线程池和三个线程同时并发比有什么优势线程池的优势主要体现在资源复用降低开销线程创建销毁需要内核态操作如系统调用开销较大。线程池会复用核心线程避免频繁创建线程尤其在任务量大时能显著减少资源消耗。而三个固定线程若任务超过负载要么排队等待效率低要么需要临时新建线程开销高。控制并发强度避免资源耗尽线程池通过最大线程数和队列限制并发数防止线程无限制创建比如瞬间1000个任务直接创建1000个线程可能导致CPU内存耗尽)。而三个线程若面对突发大量任务要么处理不过来任务堆积)要么手动扩容线程难以控制)。任务管理更灵活线程池支持任务排队、优先级调度、拒绝策略等能应对任务峰值如秒杀场景的突发请求)。而三个线程的并发方式缺乏这些机制任务处理逻辑会和业务代码耦合如手动写队列、处理超时)。线程池中shutdown ()shutdownNow()这两个方法有什么作用shutdown调用后状态置为 SHUTDOWN已提交但未开始执行的队列任务仍会按顺序继续执行直到全部完成只对处于空闲等待状态的 worker线程调用interrupt()。此后不能再往线程池中添加任何任务否则将拋出RejectedExecutionException 异常而 shutdownNow 为STOP并试图停止所有正在执行的线程不再处理还在池队列中等待的任务当然它会返回那些未执行的任务。它试图终止线程的方法是通过调用Thread.interrupt() 方法来实现的但是这种方法的作用有限如果线程中没有sleep、wait、Condition、定时锁等应用interrupt()方法是无法中断当前的线程的。所以ShutdownNow()并不代表线程池就一定立即就能退出它可能必须要等待所有正在执行的任务都执行完成了才能退出。提交给线程池中的任务可以被撤回吗可以当向线程池提交任务时会得到一个Future对象。这个Future对象提供了几种方法来管理任务的执行包括取消任务。取消任务的主要方法是Future接口中的cancelboolean mayInterruptIfRunning方法。这个方法尝试取消执行的任务。参数mayInterruptIfRunning指示是否允许中断正在执行的任务。

相关文章:

八股整理之JUC篇

怎么保证多线程安全?synchronized关键字:可以使用synchronized关键字来同步代码块或方法,确保同一时刻只有一个线程可以访问这些代码。对象锁是通过synchronized关键字锁定对象的监视器(monitor)来实现的。volatile关键字:volatil…...

中间件简单题目教学

题目1:环境搭建与简单模式使用 Docker 启动 RabbitMQ 4.x 容器,用户 guest,密码 123456,映射管理端口 15672。编写 Java 原生生产者,向队列 test_queue 发送消息 "Hello Exam"。编写 Java 原生消费者&#x…...

2026年降AI工具万方检测专项测试:五款工具万方AIGC检测通过率完整横评

2026年降AI工具万方检测专项测试:五款工具万方AIGC检测通过率完整横评 选工具之前做了一周功课,试用了三款,最后定了嘎嘎降AI(www.aigcleaner.com)。 4.8元,知网AI率从61%降到了5.3%,达标率99…...

实验7全流程

## 实验七:微服务综合项目实战(零基础全流程)本实验基于 **Spring Boot 3.5.x** **Spring Cloud 2025.0.1** **RabbitMQ 4.2.3** **Redis 7.x**,带你从零搭建一个完整的电商下单系统: **用户请求 → Gateway网关 …...

Linux守护进程--进程、进程组、会话、终端

要弄明白守护进程,就必须先讲清楚进程、进程组、会话、终端一、进程当我们运行一个应用时,根据冯诺依曼体系结构,必须把这个应用的代码、数据以及PCB(进程控制块,process control block,也就是关于进程的描述结构体)加…...

从张宇考研课到Matlab实战:手把手教你用Grunwald-Letnikov公式实现分数阶求导

从数学理论到代码实践:Grunwald-Letnikov公式在分数阶求导中的完整实现路径 当我们在学习传统微积分时,整数阶导数(如一阶导数表示变化率,二阶导数表示曲率)的概念已经深入人心。然而,数学的世界远不止于此…...

QGIS 3.28.3 保姆级教程:手把手教你下载天地图影像/矢量瓦片(附完整参数与避坑指南)

QGIS 3.28.3 天地图数据获取全攻略:从零配置到高效下载 天地图作为国内权威的地理信息数据源,为开发者、学生和研究人员提供了丰富的影像和矢量数据。但对于刚接触QGIS的新手来说,如何正确配置参数、避开常见陷阱并高效下载所需数据&#xff…...

告别手动Excel!用Plink 1.9快速搞定GWAS数据杂合度分析(附实战代码)

群体遗传学实战:用Plink高效完成GWAS数据杂合度分析 在生物信息学研究中,杂合度分析是评估基因型数据质量的重要环节。传统手动Excel处理方式不仅耗时耗力,还容易引入人为错误。本文将详细介绍如何利用Plink 1.9这一专业工具,快速…...

将OpenSSH集成到OpenHarmony系统镜像:从编译到system分区的完整部署流程

OpenHarmony系统镜像中集成OpenSSH的工程化实践 在物联网设备快速普及的今天,安全远程管理成为嵌入式系统开发中不可或缺的一环。作为开源鸿蒙生态的核心,OpenHarmony系统需要提供完善的远程访问能力,而OpenSSH作为行业标准的加密通信工具&am…...

终极Android虚拟定位指南:无需Root,让你的手机“瞬间移动“到世界任何角落!

终极Android虚拟定位指南:无需Root,让你的手机"瞬间移动"到世界任何角落! 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 想象一下&…...

GD32F4xx内部FLASH读写避坑指南:从用户手册到代码调试,手把手教你搞定0x08040000地址操作

GD32F4xx内部FLASH操作实战:从手册解读到调试验证的完整指南 第一次接触GD32F4系列MCU的内部FLASH操作时,很多开发者都会遇到各种"坑":为什么擦除后数据变成了0xFF?为什么写入操作会失败?地址0x08040000到底…...

STM32F407VE的FSMC时序调优笔记:如何让320x480的ILI9488屏幕刷得更快更稳

STM32F407VE的FSMC时序调优笔记:如何让320x480的ILI9488屏幕刷得更快更稳 当一块320x480分辨率的ILI9488屏幕在STM32F407VE上成功点亮后,真正的挑战才刚刚开始。许多工程师会发现,虽然屏幕能显示内容,但刷新率低下、画面闪烁甚至偶…...

STM32串口打印的“坑”你踩过几个?从fputc重定向到解决中文乱码、数据丢失的完整指南

STM32串口打印的“坑”你踩过几个?从fputc重定向到解决中文乱码、数据丢失的完整指南 调试嵌入式系统时,串口打印是最常用的调试手段之一。对于STM32开发者来说,将printf重定向到USART看似简单,但在实际项目中往往会遇到各种意料之…...

淘宝淘金币自动化脚本:每天节省25分钟的数字生活革命

淘宝淘金币自动化脚本:每天节省25分钟的数字生活革命 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本,包含蚂蚁森林收取能量,芭芭农场全任务,解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taojinbi 你是否…...

【论文阅读】从过程技能到策略基因:走向经验驱动的测试时进化 From Procedural Skills to Strategy Genes: Towards Experience-Driven

从过程技能到策略基因:走向经验驱动的测试时进化 From Procedural Skills to Strategy Genes: Towards Experience-Driven Test-Time Evolution 作者:Junjie Wang˒* Yiming Ren˒* Haoyang Zhang* InfiniteEvolutionLab, EvoMap 清华大学 wangjunjie@sz.tsinghua.edu.cn…...

我做了一个仅有 1.3 MB 的 macOS 原生 AI 助手:AskNow

我就问个问题,怎么占用我一个多G的内存! 近半年以来,我们的信息流几乎被 Agent 刷屏。 Claude Code、Codex、OpenClaw,以及各种各样的 AI 应用都在快速出现。大家都在说:AI 已经不只是聊天机器人了,现在是 …...

智能手表核心升级:三星OLED与4nm处理器如何重塑用户体验

1. 项目概述:一次旗舰智能手表核心元件的深度迭代最近看到一条关于谷歌Pixel Watch 2的消息,核心信息点很明确:屏幕将由三星供应OLED面板,同时处理器将升级到4纳米制程。这看起来只是两个硬件参数的简单罗列,但对于我们…...

告别抓包焦虑:Win10下搞定8812BU网卡驱动与Omnipeek联动的保姆级避坑指南

告别抓包焦虑:Win10下搞定8812BU网卡驱动与Omnipeek联动的保姆级避坑指南 在无线网络分析领域,8812BU芯片的无线网卡因其出色的抓包能力备受青睐,但许多用户在Windows 10环境下配置驱动与Omnipeek抓包工具时,往往会陷入驱动安装失…...

MySql学习杂谈 --- “连接“”

第一步:忘掉所有术语,记住一个生活场景 想象你要做一件事:查全班同学的考试成绩 表A(同学名单):张三,李四,王五,赵六 表B(考试成绩)&#xff1…...

i.MX8M Mini核心板Linux 6.1 BSP升级:内存带宽翻倍与嵌入式开发实战

1. 项目概述:当i.MX8M Mini遇上Linux 6.1作为一名在嵌入式行业摸爬滚打了十多年的老鸟,我见证过无数次芯片迭代和系统升级。最近,飞凌嵌入式为他们的FETMX8MM-C核心板推送了基于Linux 6.1的全新BSP(Board Support Package&#xf…...

北光恒电:安捷伦6812B/6813B电源不开机、输出不正常故障排查

安捷伦6812B/6813B电源作为高精度交流电源/功率分析仪,广泛应用于电源测试、UPS测试、航空电子ATE等场景,凭借稳定性能成为实验室和生产线上的核心设备。长期使用或操作不当,不开机、输出不正常等故障频发,影响测试效率。常见故障…...

某包丨图片+视频去水印去除工具

首先下载软件(工具在末尾),然后运行,自动打开网页如下: 接着打开某包,找到你要去除水印的图片或者视频的链接: 工具下载: 链接:https://pan.quark.cn/s/aec2cdde94ed...

注册培训师、咨询师——杨刚老师简介

注册培训师、咨询师——杨刚老师简介注册培训师、咨询师 MTP认证讲师——日本产业训练协会认证 世界500强管理目视化解决方案 版权持有人 杨老师具备10年生产管理经验、15年培训及咨询辅导经验。曾任某日资企业制作课课长、某上市企业精益经理、某民营企业绩效经理、某咨…...

定向井轨迹控制关键技术:200℃高温定向传感器的随钻测量应用指南

一、引言 定向井钻井技术是现代油气资源开发的核心支撑技术之一,通过精确控制井眼轨迹,可以实现从地表向地下油气藏的精准穿藏,最大化油气产量和采收率。200℃定向传感器作为随钻测量系统的核心感知器件,在深井、超深井以及复杂结…...

拒绝“拍脑袋“备货:武汉丝路云如何利用Flink实时计算打造跨境供应链的“数据大脑“?

前言 在之前的文章中(如《揭秘跨境供应链的高并发架构》),我们探讨了如何通过微服务架构保证系统在"黑五"大促时不崩溃。但很多客户反馈了一个更深层的问题: "系统确实不崩了,但库存还是积压。要么备货…...

给 AI 写一份老厨师的菜谱:从传统文档到 Skill 知识体系

大家好,我是程序员小策。 先跟你讲三个故事—— 故事一: 你点了一份红烧肉,菜谱上写着"五花肉 500g,酱油适量,冰糖少许,小火慢炖"。你照着做了,出来的肉又柴又腥。为什么?…...

终极指南:使用Play Integrity API Checker保护你的Android应用安全

终极指南:使用Play Integrity API Checker保护你的Android应用安全 【免费下载链接】play-integrity-checker-app Get info about your Device Integrity through the Play Intergrity API 项目地址: https://gitcode.com/gh_mirrors/pl/play-integrity-checker-a…...

PCB直流电阻精确估算:从基础公式到工程实践的全解析

1. 项目概述:为什么需要精确估算PCB直流电阻? 在硬件设计,尤其是电源完整性、信号完整性和热管理的世界里,PCB走线的直流电阻常常是一个被低估的关键参数。很多工程师在设计初期,注意力都集中在阻抗匹配、串扰和EMI上&…...

Linux信号机制深度解析:从内核实现到多线程编程实践

1. 信号的角色与核心概念 信号,这个在Unix/Linux世界里存在了超过三十年的机制,至今仍然是进程间通信和内核与进程交互的基石。简单来说,信号就是内核发给进程的一个简短通知,告诉它“有事情发生了”。你可以把它想象成你手机上的…...

毕业设计作品精选【芳心科技】基于STM32的智能家庭快递柜

实物效果图:实现功能:本设计的基于STM32单片机的智能家庭快递柜,需要及进行硬件没计和软件开发。硬件方面,需要选择合适的矩阵键盘、显示器、LED灯、电动机等硬件没备,并设计相应的电路来连接各个模块。软件方面&#…...