synchronized锁
synchronized 关键字是锁的一种实现
class X {
// 修饰非静态方法
// 当修饰非静态方法的时候,锁定的是当前实例对象 this
synchronized void foo() {
// 临界区
}
// 修饰静态方法
// 当修饰静态方法的时候,锁定的是当前类的 Class 对象
synchronized static void bar() {
// 临界区
}
// 修饰代码块
Object obj = new Object();
void baz() {
synchronized(obj) {
// 临界区
// 锁定obj 对象
}
}
}
- 当修饰非静态方法的时候,锁定的是当前实例对象 this
- 当修饰静态方法的时候,锁定的是当前类的 Class 对象
- 当修饰代码块的时候,锁定的是传入的对象
加锁 lock() 和解锁 unlock() 是被 Java 默默加上的,Java 编译器会在 synchronized 修饰的方法或代码块前后自动加上加锁 lock() 和解锁 unlock()
class SafeCalc {
long value = 0L;
synchronized long get() {
return value;
}
synchronized void addOne() {
value += 1;
}
}

把 value 改成静态变量,把 addOne() 方法改成静态方法
class SafeCalc {
static long value = 0L;
synchronized long get() {
return value;
}
synchronized static void addOne() {
value += 1;
}
}
改动后的代码是用两个锁保护一个资源。这个受保护的资源就是静态变量 value,两个锁分别是 this 和 SafeCalc.class

由于临界区 get() 和 addOne() 是用两个锁保护的,因此这两个临界区没有互斥关系,临界区 addOne() 对 value 的修改对临界区 get() 也没有可见性保证,这就会导致并发问题了
class SafeCalc {
long value = 0L;
long get() {
synchronized (new Object()) {
return value;
}
}
void addOne() {
synchronized (new Object()) {
value += 1;
}
}
}
可以用一把锁来保护多个资源,但是不能用多把锁来保护一个资源
用不同的锁对受保护资源进行精细化管理,能够提升性能。叫细粒度锁
- 如果资源之间没有关系,很好处理,每个资源一把锁就可以了。
- 如果资源之间有关联关系,就要选择一个粒度更大的锁,这个锁应该能够覆盖所有相关的资源。
每个人都有潜在的能量,只是很容易被习惯所掩盖,被时间所迷离,被惰性所消磨~

浙公网安备 33010602011771号