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

synchronized(this) 用法详解

基本概念

synchronized(this) 是 Java 中的一种同步机制,通过对当前对象实例加锁来保证线程安全。当一个线程进入被 synchronized(this) 修饰的代码块时,会获取当前对象的锁,其他线程必须等待该线程释放锁后才能进入。

基本语法

public class MyClass {public void method() {synchronized(this) {// 需要同步保护的代码// 同一时刻只有一个线程能执行这里的代码}}
}

使用场景详解

1. 实例变量的线程安全操作

public class Counter {private int count = 0;// 不安全的递增方法public void unsafeIncrement() {count++; // 非原子操作,可能出现竞态条件}// 安全的递增方法public void safeIncrement() {synchronized(this) {count++;}}// 获取当前计数值public int getCount() {synchronized(this) {return count;}}
}

2. 复杂业务逻辑的原子性保证

public class BankAccount {private double balance;public BankAccount(double initialBalance) {this.balance = initialBalance;}public boolean withdraw(double amount) {synchronized(this) {// 检查余额是否充足if (balance >= amount) {// 模拟处理时间try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}balance -= amount;return true;}return false;}}public void deposit(double amount) {synchronized(this) {// 模拟处理时间try {Thread.sleep(50);} catch (InterruptedException e) {Thread.currentThread().interrupt();}balance += amount;}}public double getBalance() {synchronized(this) {return balance;}}
}

3. 多步骤操作的原子性保证

public class InventoryManager {private Map<String, Integer> inventory = new HashMap<>();public InventoryManager() {// 初始化库存inventory.put("item1", 100);inventory.put("item2", 50);}// 批量扣减库存 - 需要保证原子性public boolean deductInventory(Map<String, Integer> itemsToDeduct) {synchronized(this) {// 第一步:检查所有商品库存是否充足for (Map.Entry<String, Integer> entry : itemsToDeduct.entrySet()) {String itemId = entry.getKey();Integer quantity = entry.getValue();Integer currentStock = inventory.get(itemId);if (currentStock == null || currentStock < quantity) {return false; // 库存不足,整个操作失败}}// 第二步:扣减所有商品库存for (Map.Entry<String, Integer> entry : itemsToDeduct.entrySet()) {String itemId = entry.getKey();Integer quantity = entry.getValue();Integer currentStock = inventory.get(itemId);inventory.put(itemId, currentStock - quantity);}return true;}}public int getStock(String itemId) {synchronized(this) {return inventory.getOrDefault(itemId, 0);}}
}

4. 缓存更新的线程安全

public class CachedDataService {private Map<String, Object> cache = new HashMap<>();private long lastUpdateTime = 0;private static final long CACHE_TIMEOUT = 60000; // 1分钟public Object getData(String key) {synchronized(this) {// 检查缓存是否过期if (System.currentTimeMillis() - lastUpdateTime > CACHE_TIMEOUT) {refreshCache();}return cache.get(key);}}public void putData(String key, Object data) {synchronized(this) {cache.put(key, data);lastUpdateTime = System.currentTimeMillis();}}private void refreshCache() {// 刷新缓存逻辑cache.clear();// 重新加载数据...lastUpdateTime = System.currentTimeMillis();}public void clearCache() {synchronized(this) {cache.clear();lastUpdateTime = 0;}}
}

与其他同步方式的比较

1. synchronized 方法 vs synchronized(this)

public class ComparisonExample {private int value = 0;// 方式1:同步整个方法public synchronized void method1() {value++;// 其他操作...}// 方式2:同步代码块public void method2() {// 一些不需要同步的操作System.out.println("不需要同步的操作");synchronized(this) {value++;// 需要同步的操作}// 更多不需要同步的操作System.out.println("更多不需要同步的操作");}
}

2. synchronized(this) vs synchronized(object)

public class LockGranularityExample {private final Object lock1 = new Object();private final Object lock2 = new Object();private int counter1 = 0;private int counter2 = 0;// 粗粒度锁定 - 锁定整个对象public void coarseGrainedOperation() {synchronized(this) {counter1++;counter2++;}}// 细粒度锁定 - 分别锁定不同的资源public void fineGrainedOperation() {synchronized(lock1) {counter1++;}synchronized(lock2) {counter2++;}}
}

实际应用场景

1. 单例模式中的懒加载

public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {synchronized(LazySingleton.class) {if (instance == null) {instance = new LazySingleton();}}}return instance;}
}

2. 生产者-消费者模式

public class Buffer {private final Queue<Integer> queue = new LinkedList<>();private final int capacity = 10;public void produce(int item) throws InterruptedException {synchronized(this) {while (queue.size() == capacity) {// 缓冲区满,等待消费者消费wait();}queue.offer(item);System.out.println("生产: " + item);notifyAll(); // 通知等待的消费者}}public int consume() throws InterruptedException {synchronized(this) {while (queue.isEmpty()) {// 缓冲区空,等待生产者生产wait();}int item = queue.poll();System.out.println("消费: " + item);notifyAll(); // 通知等待的生产者return item;}}
}

3. 状态机的状态转换

public class StateMachine {private enum State {IDLE, PROCESSING, COMPLETED, ERROR}private State currentState = State.IDLE;public void startProcessing() {synchronized(this) {if (currentState == State.IDLE) {currentState = State.PROCESSING;System.out.println("开始处理...");} else {throw new IllegalStateException("不能从 " + currentState + " 状态开始处理");}}}public void completeProcessing() {synchronized(this) {if (currentState == State.PROCESSING) {currentState = State.COMPLETED;System.out.println("处理完成");} else {throw new IllegalStateException("不能在 " + currentState + " 状态完成处理");}}}public State getCurrentState() {synchronized(this) {return currentState;}}
}

注意事项和最佳实践

1. 避免死锁

public class DeadlockAvoidance {private final Object lockA = new Object();private final Object lockB = new Object();// 错误的做法 - 可能导致死锁public void badMethod1() {synchronized(lockA) {synchronized(lockB) {// 操作...}}}public void badMethod2() {synchronized(lockB) {synchronized(lockA) {// 操作...}}}// 正确的做法 - 统一加锁顺序public void goodMethod1() {synchronized(lockA) {synchronized(lockB) {// 操作...}}}public void goodMethod2() {synchronized(lockA) {  // 保持相同的加锁顺序synchronized(lockB) {// 操作...}}}
}

2. 减少锁的持有时间

public class LockHoldingOptimization {private List<String> dataList = new ArrayList<>();// 不好的做法 - 锁持有时间过长public void badPractice() {synchronized(this) {// 执行耗时操作expensiveOperation();// 添加数据dataList.add("data");}}// 好的做法 - 减少锁持有时间public void goodPractice() {// 先执行耗时操作String result = expensiveOperation();// 只在必要时加锁synchronized(this) {dataList.add(result);}}private String expensiveOperation() {// 模拟耗时操作try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();}return "processed_data";}
}

总结

synchronized(this) 的主要特点和使用建议:

适用场景:

保护实例变量的并发访问
保证多步骤操作的原子性
实现简单的线程同步

注意事项:

锁的是当前对象实例,同一类的不同实例之间不会互斥
可能影响性能,应尽量减少锁的持有时间
注意避免死锁

替代方案:

对于更复杂的并发控制,可以考虑使用 java.util.concurrent 包中的工具类
对于读多写少的场景,可以考虑使用 ReentrantReadWriteLock
对于无锁编程,可以考虑使用 Atomic 类

synchronized(this) 是 Java 中最基础也是最重要的同步机制之一,正确使用能够有效解决大部分线程安全问题。

http://www.jsqmd.com/news/53080/

相关文章:

  • 项目写交付文档,数据库文档生成
  • 2025年琉璃瓦厂家推荐排行榜:哪家好?哪家靠谱?选哪家?——基于 CNPP 榜单的对比评测
  • Kafka在Spring Boot生态中的浅析与应用 - 教程
  • 2025年11月成都电线电缆厂家最新推荐,高压电缆、中压电缆、低压电缆、铜芯电缆、铝芯电缆、企业综合服务能力与产品特色深度解析
  • 2025 年最新屏蔽泵厂家排行榜:高温 / 自吸 / 化工等多类型屏蔽泵最新推荐,助力企业精准选品立式 / 液下 / 多级 / 维修 / 低温 / 液化气屏蔽泵推荐
  • NeurIPS 2025|让AI读懂第一视角的“内心独白”!浙大等联合突破性实现自我中心视频推理
  • 实验5 MapReduce初级编程实践
  • 2025年燃气低氮热水锅炉加工厂权威推荐榜单:家庭燃气热水锅炉/立式卧式燃气热水锅炉/半吨燃气热水锅炉设备源头厂家精选
  • 08.入门篇-Java程序运行原理
  • rust关键字unsafe
  • 完整教程:TouchDIVER Pro 触觉手套:Weart把火星岩石触感、手术操作感搬进 XR
  • 2025 年液化气泵厂家最新推荐榜,聚焦技术创新与质量保障的优质品牌深度解析无密封/磁力/倒罐/双端面机械密封/屏蔽/增压液化气泵公司推荐
  • 【水印检查】字符串处理和矩阵的存入
  • 高品质牛肉品牌推荐:安心之选,守护家庭餐桌
  • 06.入门篇-AI编程助手
  • 中药品牌十强排名彰显实力,好医生以完整产业链布局未来
  • 2025年11月电线电缆最新推荐厂家,高压电缆、中压电缆、低压电缆、铜芯电缆、铝芯电缆、铝合金电缆多维度综合考量
  • 从零部署网站客服系统:我踩过的域名和服务器坑,帮你省下几千块!
  • U634637 Star way to heaven
  • 【51单片机】【protues仿真】基于51单片机自动浇花强大的系统
  • 2025 年不锈钢水管厂家最新推荐榜,深度剖析品牌技术实力与市场口碑的核心竞争力薄壁/沟槽/卫生级/环压/快装/316/卡压式不锈钢水管/不锈钢水管工程/不锈钢水管管件/不锈钢水管安装公司推荐
  • 产学研融合!2025年中成药品牌排行榜10强好医生集团的创新引擎
  • FrameWork4.5 项目下使用EF6 同一项目操作多种数据库
  • 微波烘干设备厂家技术实力与行业应用解析
  • 2025年定期排污扩容器生产商权威推荐榜单:电厂疏水扩容器/定连排疏水扩容器/定期排污疏水扩容器源头厂家精选
  • 2025 年最新推荐激光切管机厂家排行榜:聚焦高效高精度设备,助力企业提升金属管材加工品质高速 / 高精度 / 零尾料 / 免画图 / 全自动 / 三卡盘激光切管机公司推荐
  • 2025 年升降柱机芯厂家最新推荐榜,技术实力与市场口碑深度解析,筛选高性能可靠货源IP68 升降柱机芯 / 防撞升降柱机芯 / 低压升降柱机芯 / 液压升降柱机芯 / 路障机升降柱机芯公司推荐
  • 不只是制药!中药品牌排行榜10强好医生,用石榴谱写产业富民传奇
  • java 上转型对象调用
  • 比较好吸收的奶粉怎么选?这篇文章里有答案