03 互斥锁

2021-08-02  本文已影响0人  hopi

synchronized 关键字

修饰静态方法:定的是当前类的 Class 对象

class Clz {
  // 修饰静态方法
  synchronized static void m() {}
  // 上面相当于
  synchronized(X.class) static void m() {}
}  

修饰非静态方法:锁定的是当前实例对象 this

class Clz {
  // 修饰静态方法
  synchronized void m() {}
  // 上面相当于
  synchronized(this) void m() {}
}  

修饰代码块:锁定指定对象

class Clz {
  // 修饰代码块
  Object obj = new Object();
  void m() {
    // 锁定 obj 对象
    synchronized(obj) {
        // 代码块
    }
  }
}  

思考题 1

class Test {
  long value = 0L;
  // get 方法的 synchronized 关键字是必须的吗? 
  synchronized long get() {
    return value;
  }
  synchronized void add() {
    value += 1;
  }
} 

如 get 方法不加 synchronized 关键字,就意味着 get 方法没受管程约束。不能保证访问 value 变量的可见性。所以不是线程安全的。所以synchronized 关键字是必须的。

get 方法需要加锁保护

思考题 2

// 通过下面源码画出锁的对应关系
class Test {
  static long value = 0L;
  synchronized long get() {
    return value;
  }
  synchronized static void add() {
    value += 1;
  }
}

get 方法和 add 方法分别加了不同的所,所以源码为非线程安全。

锁对应关系

注意事项

  1. 理清资源与锁的关系。
  2. 解决原子性问题,要保证中间状态对外不可见。
  3. 不能使用可变对象做锁。
上一篇 下一篇

猜你喜欢

热点阅读