互斥锁

2020/12/29 posted in  并发基础

互斥锁 -- 解决并发的原子性问题

锁模型


synchronized

class X {
  // 修饰非静态方法 锁定当前的实例对象
  synchronized void foo() {
    // 临界区
  }
  // 修饰静态方法 锁为当前类的Class对象
  synchronized static void bar() {
    // 临界区
  }
  // 修饰代码块
  Object obj = new Object();
  void baz() {
    synchronized(obj) {
      // 临界区
    }
  }
}  



锁和受保护资源之间的关系


合理的关系是 : 受保护资源和锁之间合理的关联关系应该是 N:1 的关系

  1. 保护没有关联关系的资源:用不同的锁保护不同的资源,细化锁的粒度,提升性能
  2. 保护有关联关系的资源:覆盖所有资源



原子性

本质是中间状态对外不可见

死锁

一组相互竞争资源的线程因相互等待,导致永久性阻塞的问题


死锁产生原因

  1. 互斥:共享资源X和Y只能被同一线程占用
  2. 占有且等待:线程T1占有X资源,在等待获取资源Y的时候不释放X资源
  3. 不可抢占:其他线程不能抢占线程T1所占资源
  4. 循环等待:线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源



预防死锁

互斥是目的不能破坏,其他三个破坏其中的一个就可以

  1. ’占有且等待‘ : 一次性申请所需的资源
  2. ’不可抢占‘ : 占有资源的线程申请时如果申请不到,则释放自己持有的资源
  3. ’循环等待‘ : 按序申请资源

等待通知

如果线程不满足条件阻塞自己,进入等待状态,当线程满足条件时,通知等待的线程继续执行

synchronized 实现等待-通知