Java并发17:Lock接口与ReentrantLock - 更灵活的锁

引言:synchronized的局限性 在前面的文章中,我们深入学习了synchronized,但它有一些局限性: public class SynchronizedLimitations { private final Object lock = new Object(); public void method() { synchronized (lock) { // 问题1:无法响应中断 // 如果获取锁的线程被阻塞,无法中断它 // 问题2:无法设置超时 // 如果获取不到锁,会一直等待 // 问题3:必须在同一个代码块中释放锁 // 无法在方法A获取,方法B释放 // 问题4:无法尝试非阻塞获取锁 // 无法tryLock() // 问题5:无法实现公平锁 // synchronized是非公平的 } } } JDK 1.5引入Lock接口,解决这些问题: Lock lock = new ReentrantLock(); // 可响应中断 lock.lockInterruptibly(); // 可设置超时 boolean success = lock.tryLock(1, TimeUnit.SECONDS); // 可尝试非阻塞获取 if (lock.tryLock()) { try { // ... } finally { lock.unlock(); } } // 可实现公平锁 Lock fairLock = new ReentrantLock(true); 本篇文章将深入Lock接口和ReentrantLock的实现原理。 ...

2025-11-20 · maneng

线程安全与同步机制:从synchronized到Lock的演进

引子:一个购物车的线程安全之路 在上一篇文章中,我们理解了并发编程的三大核心问题:可见性、原子性、有序性。现在我们要解决这个问题:如何让多线程安全地访问共享数据? 场景:电商购物车的并发问题 /** * 购物车服务(线程不安全版本) * 问题:多个线程同时添加商品,可能导致数据丢失 */ public class ShoppingCart { private Map<String, Integer> items = new HashMap<>(); // 商品ID → 数量 // 添加商品到购物车 public void addItem(String productId, int quantity) { Integer currentQty = items.get(productId); if (currentQty == null) { items.put(productId, quantity); } else { items.put(productId, currentQty + quantity); } } // 获取购物车总商品数 public int getTotalItems() { int total = 0; for (Integer qty : items.values()) { total += qty; } return total; } } // 并发测试 public class CartTest { public static void main(String[] args) throws InterruptedException { ShoppingCart cart = new ShoppingCart(); // 10个线程并发添加商品 Thread[] threads = new Thread[10]; for (int i = 0; i < 10; i++) { threads[i] = new Thread(() -> { for (int j = 0; j < 100; j++) { cart.addItem("product-123", 1); } }); } for (Thread t : threads) t.start(); for (Thread t : threads) t.join(); System.out.println("期望数量:1000"); System.out.println("实际数量:" + cart.getTotalItems()); } } /* 执行结果(多次运行不一致): 第1次:实际数量:856 ❌ 丢失144次更新 第2次:实际数量:923 ❌ 丢失77次更新 第3次:实际数量:891 ❌ 丢失109次更新 问题分析: 1. HashMap本身不是线程安全的 2. addItem方法不是原子操作(读取、计算、写入三步) 3. 多线程并发执行导致数据竞争 解决方案演进: Level 1:使用synchronized → 简单但粗粒度 Level 2:使用ReentrantLock → 灵活但需要手动管理 Level 3:使用ConcurrentHashMap → 高性能(下一篇讲解) */ 本文将深入探讨如何通过synchronized和Lock来保证线程安全。 ...

2025-11-03 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...