锁的几种应用场景
2026-01-08
首先嘛,最简单的就是单通道执行。【用synchronized加实例方法或类方法,synchronized(lock){}】

场景2:读和写并发进行(不加锁),但是修改是原子操作。用AtomicInteger等类实现
多线程访问的全局变量int就要用AtomicInteger [低频竞争感觉不明显,高频竞争如果不用AtomicXXX就会出幽灵数字。即A在写它的时候,B也在写,最后出现了一个不是A也不是B的数字]
场景3:取号机制。秒杀时防止超卖。用CAS(其实是无锁机制)。拿到号就去下单,没拿到号(竞争失败)就返回失败。
@RestController public class CASController { AtomicInteger store = new AtomicInteger(5); @GetMapping("/lock/cas/order") // 定义GET请求接口,路径为/hello public String set() throws InterruptedException { do{ int s = store.get(); if(s<=0){ return "无库存了"; } if(store.compareAndSet(s, s-1)){ //这里处理下单逻辑 return String.valueOf(s); } Thread.sleep(100); }while (true); } }
场景4:写的时候,阻塞读。保证数据严格统一。即在写之前必须读的是旧数据,在写中或者说写后,读的必须是新数据。 没有写的时候,无锁读。
public class ReentrantLockTest { ReentrantLock lock = new ReentrantLock(); AtomicInteger age = new AtomicInteger(100); public int read(){ if(lock.isLocked()){ lock.lock(); try{ return age.get(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } return age.get(); } public void write(int newAge){ lock.lock(); try{ age.set(newAge); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } }
jdk原生是有支持类的:就是 ReentrantReadWriteLock
当写锁被持有(无论是否是当前线程)时,其他线程的读锁会被阻塞。ReentrantReadWriteLock 遵循 “读写互斥、写写互斥、读读共享” 的核心规则,写锁的独占性会直接阻塞后续的读操作请求。
场景5:生产者和消费者模式,当无资源消费时,就阻塞等待,直到有被生产者唤醒。
posted on 2026-01-08 14:22 angelshelter 阅读(1) 评论(0) 收藏 举报
浙公网安备 33010602011771号