avatar
文章
286
标签
48
分类
10
首页
时间轴
分类
关于
Logo只有那年胜过年年
搜索
首页
时间轴
分类
关于

只有那年胜过年年

Synchronized关键字的五种应用场景详解
发表于2025-10-14|后端
synchronized 是Java中最基本的线程同步关键字,其核心思想是通过互斥锁来保证同一时刻只有一个线程能访问特定代码或对象。根据锁定的范围不同,synchronized的用法主要可分为以下五类。 同步实例方法将关键字直接修饰在普通成员方法上。 javapublic class Counter {private int value = 0; // 锁住整个当前实例对象 (this) public synchronized void increment() { value++; } public synchronized int getValue() { return value; } }锁对象:当前实例对象 (this)。作用范围:同一实例的所有同步实例方法互斥。不同实例间的同步不互相影响。注意事项:若使用单例模式,则能达到全局互斥效果;否则,需确保多线程操作的是同一个实例。 同步静态方法将关键字直接修饰在静态方法上。 javapublic class StaticCounter {private static int value &#...
Synchronized与ReentrantLock:内置锁与显式锁的全面对比
发表于2025-10-14|后端
在Java并发编程中,synchronized 关键字和 ReentrantLock 类是两种最核心的互斥同步工具。理解它们的异同,对于做出正确的技术选型至关重要。 对比总览特性维度 synchronized (内置锁/监视器锁) ReentrantLock (显式锁)实现层级 JVM层面实现,属于语言原生特性。 JDK层面实现,基于 java.util.concurrent.locks 包。锁的获取与释放 自动管理。进入同步块自动获取,退出(正常或异常)自动释放。 手动控制。必须显式调用 lock() 和 unlock(),通常将unlock() 置于 finally 块。可重入性 支持。同一线程可多次进入。 支持。同一线程可多次锁定,需对应次数的解锁。锁的公平性 仅支持非公平锁(默认,吞吐量高)。 支持公平与非公平锁(通过构造器参数选择)。公平锁按等待顺序获取,减少“饥饿”,但性能较低。性能 早期性能较差。JDK 1.6后引入“锁升级”(偏向->轻量级->重量级)优化,在低竞争下性能与ReentrantLock接近。性能稳定。在高竞争场景下,其可伸...
sleep() 与 wait():线程暂停方法的深度辨析
发表于2025-10-14|后端
sleep() 和 wait() 是Java多线程中用于暂停线程执行的两种核心方法。虽然它们都能让线程“停下来”,但其设计目的、使用机制和底层行为存在本质区别。 五大核心区别详解对比维度 Thread.sleep(long millis) Object.wait(long timeout) 方法与归属 Thread 类的静态本地方法。 Object 类的实例本地方法。 调用限制 可在任何地方调用,无需获取锁。但需捕获 InterruptedException。 必须在同步代码块或同步方法中调用,且调用线程必须已获得该对象的监视器锁(monitorlock)。同样需捕获 InterruptedException。 锁的行为 不会释放 任何已持有的锁。线程休眠时仍持有锁。 会释放 调用该方法的对象锁。这是实现线程间协调的关键。 唤醒机制 休眠指定时间后自动恢复,或可被中断。 1) 超时后自动恢复;2) 被中断;3) 必须由其他线程调用同一对象的 notify() 或notifyAll() 来唤醒。唤醒后需重新竞争锁。 设计目的 单纯地让当前线程暂停执行一段时间,用于计时、节流...
ArrayList并发修改异常的典型表现与根源
发表于2025-10-14|后端
ArrayList 作为Java中最常用的集合类之一,其非线程安全的特性是并发编程中的经典考点。理解其在多线程环境下可能出现的各种异常现象,有助于我们加深对线程安全必要性的认识。 并发问题复现javaimport java.util.ArrayList;import java.util.List; public class UnsafeArrayListDemo {private static List numberList = new ArrayList<>(); public static void main(String[] args) throws InterruptedException { // 模拟10次并发测试 for (int testRound = 0; testRound < 10; testRound++) { testConcurrentAdd(); numberList.clear(); // 清空为下一轮测试准备 } } private static void te...
构建线程安全List的演进之路:从Vector到CopyOnWrite
发表于2025-10-14|后端
当面试官追问如何解决 ArrayList 的线程安全问题,仅仅回答 Vector 是远远不够的。这展现了知识面的狭窄。从早期的同步容器到现代的并发容器,Java提供了多种方案,各有其适用场景。 第一代方案:完全同步的容器 VectorVector 是Java早期(JDK 1.0)提供的线程安全动态数组。其实现线程安全的方式简单粗暴:在几乎所有公开方法上都加上了synchronized 关键字。 java// Vector内部方法示例public synchronized boolean add(E e) {modCount++;ensureCapacityHelper(elementCount + 1);elementData[elementCount++] = e;return true;}public synchronized E get(int index) {if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);return el...
彻底理解Java线程中断机制
发表于2025-10-14|后端
Java中的线程中断(Interruption)是一种协作式机制,用于通知一个线程“有人希望你停止正在做的事情”。它并非强制终止线程(像已废弃的Thread.stop() 那样),而是一种礼貌的请求,线程自身拥有决定如何响应的完全控制权。 中断相关核心API所有中断逻辑都围绕 Thread 类的三个方法展开: 方法 说明void interrupt() 发起中断。设置目标线程的“中断状态”为 true。如果目标线程正因 sleep(), wait(), join() 而阻塞,则会抛出InterruptedException,并清除中断状态。boolean isInterrupted() 检查中断状态。返回线程的中断状态,不清除状态标志。static boolean interrupted() 检查并清除中断状态。返回当前线程的中断状态,然后将中断状态设置为 false。响应中断的两种模式模式一:处理InterruptedException当线程在可中断的阻塞方法(如 sleep(), wait(), join())中被中断时,这些方法会抛出 Interrupte...
超越Thread.sleep():更优雅的线程休眠与时间单位转换
发表于2025-10-14|后端
线程休眠是控制线程执行节奏的常见操作。虽然 Thread.sleep(long millis)人尽皆知,但其以毫秒为单位的参数在可读性和易用性上存在不足。java.util.concurrent.TimeUnit枚举类提供了更优雅、更清晰的替代方案,同时也是一个强大的时间单位转换工具。 告别令人困惑的毫秒计算传统方式的痛点: java// 目标:休眠1天2小时30分钟15秒long totalMillis = (24 * 60 * 60 * 1000) // 1天 (2 * 60 * 60 * 1000) // 2小时 (30 * 60 * 1000) // 30分钟 (15 * 1000); // 15秒Thread.sleep(totalMillis); // 代码难以直观理解,且易计算错误使用TimeUnit的优雅方案: javaimport java.util.concurrent.TimeUnit; try {TimeUnit...
start() 与 run():启动线程与同步调用的本质区别
发表于2025-10-14|后端
在Java多线程编程中,start() 和 run() 是与线程执行密切相关的两个方法,初学者极易混淆。理解它们之间的区别,是掌握Java线程模型的基础。 角色定位run() 方法:定义在 java.lang.Runnable 接口中,是线程需要执行的任务逻辑的主体。无论是通过继承 Thread 类还是实现 Runnable接口创建线程,都必须覆盖或实现此方法。 start() 方法:定义在 java.lang.Thread 类中。它的职责是启动一个新的执行线程。调用此方法后,JVM会在底层创建一个新的操作系统线程(或映射到内核线程),然后由这个新线程去调用run() 方法。 核心区别:异步 vs 同步调用 start() 是异步的:主线程(调用者)在发出启动指令后立即返回,继续执行后续代码。新线程被放入“就绪队列”,等待操作系统调度器分配CPU时间片。一旦获得执行权,新线程便开始独立执行其run() 方法中的代码。主线程和新线程是并发执行的。 调用 run() 是同步的:这仅仅是普通的方法调用。当前线程(通常是主线程)会直接执行 run()方法体中的代码,并在此方法返回后才继续...
重入锁(ReentrantLock)深度解析:不只是可重入
发表于2025-10-14|后端
ReentrantLock 是 java.util.concurrent.locks 包中的核心类,自JDK 1.5引入。它常被称为“重入锁”,但其内涵远不止“可重入”这么简单。它提供了比传统synchronized 关键字更灵活、更强大的锁控制能力。 何为“重入”?“重入”意味着同一个线程可以多次获取同一把锁,而不会造成自我死锁。 javaReentrantLock lock = new ReentrantLock(); public void outer() {lock.lock();try {inner(); // 在持有锁的情况下调用另一个需要同一把锁的方法} finally {lock.unlock();}} public void inner() {lock.lock(); // 同一线程,可以再次获取已经持有的锁try {// 访问共享资源} finally {lock.unlock();}}如果锁不是可重入的,当线程在 outer() 中调用 inner() 时,inner() 会因无法获取锁(...
探究Thread.yield():线程礼让的语义与实效
发表于2025-10-14|后端
在Java并发工具箱中,Thread.yield() 是一个存在感较低但偶尔被提及的静态方法。它被设计为向线程调度器发出一个“暗示”,表明当前线程愿意让出当前占用的处理器资源,但这仅仅是一个建议,调度器可以自由选择忽略它。 方法定义与语义源码注释清晰地阐明了其设计意图: 向调度器暗示当前线程愿意让出当前对处理器的使用。调度器可以自由忽略此暗示。 yield是一种启发式的尝试,旨在改善那些原本会过度利用CPU的线程之间的相对进展。它的使用应结合详细的分析和基准测试,以确保它确实能达到预期效果。 很少适合使用此方法。它可能对调试或测试目的有用,有助于重现由竞态条件引起的错误。在设计并发控制结构(如java.util.concurrent.locks包中的结构)时也可能有用。 javapublic static native void yield();这是一个本地方法,其具体行为依赖于底层操作系统的线程调度器。 实践观察javapublic class YieldDemo {public static void main(String[] args) {Runnable task &#...
1…272829
avatar
2025
文章
286
标签
48
分类
10
公告
🌸 春去秋来,花开花落 📚 桌上的日历又薄了几页 💭 记忆中的昨天还那么清晰
最新文章
深入 Spring 核心机制:必知扩展点,助力成为框架高手2025-11-10
Windows 系统下 Minikube 本地 Kubernetes 环境部署指南2025-11-07
本地部署Deepseek各个版本超级详细教学,网页版、软件版2025-11-04
Java XMLDecoder 反序列化高危漏洞深度剖析2025-10-30
会话固定攻击详解2025-10-30
分类
  • 其他2
  • 区块链4
  • 后端186
  • 安全漏洞3
  • 工具26
  • 性能4
  • 教程1
  • 数据库18
  • 架构14
  • 程序人生28
标签
Linux文章JVM分布式技术其他区块链安全漏洞基础多线程性能优化架构程序人生行业动态规范进阶集合算法面试新特性DubbodockerElastic JobJWTMyBatisNettyShiroSpringSpring BootSpring CloudSpring MVCTomcatZookeeper开源日志消息队列综合技术缓存连接池EclipseGit
归档
  • 2025年11月 3
  • 2025年10月 281
  • 2025年09月 1
  • 2024年12月 1
网站信息
文章数目 :
286
本站访客数 :
本站总浏览量 :
最后更新时间 :
访客地图
© 2025 By 2025
搜索
数据加载中