Synchronized 到底锁了谁

3 minute

Synchronized 方法

1、静态方法上的锁

静态方法是属于“类”,不属于某个实例,是所有对象实例所共享的方法。也就是说如果在静态方法上加入synchronized,那么它获取的就是这个类的锁,锁住的就是这个类

2、普通方法上的锁

实例方法并不是类所独有的,每个对象实例独立拥有它,它并不被对象实例所共享。在实例方法上加入synchronized,那么它获取的就是这个类的锁,锁住的就是这个对象实例

Synchronized 代码块

1、synchronized(this){...}

this 关键字所代表的意思是该对象实例,这种用法 synchronized 锁住的是对象实例

2、synchronized(Demo.class){...}

锁的是该类

3、synchronized(obj){...}

synchronized 同步代码块对对象内部的实例加锁。

假设 demo1 与 demo2 方法不相关,此时两个线程对同一个对象实例分别调用 demo1 与 demo2,均能获取各自的锁。

代码如下:

 1public class Demo {
 2    private Object lock1 = new Object();
 3    private Object lock2 = new Object();
 4
 5    public void demo1() {
 6        synchronized (lock1) {
 7            while (true) {  //死循环目的是为了让线程一直持有该锁
 8                System.out.println(Thread.currentThread());
 9            }
10        }
11    }
12
13    public void demo2() {
14        synchronized (lock2) {
15            while (true) {
16                System.out.println(Thread.currentThread());
17            }
18        }
19    }
20}

demo1 方法中的同步代码块锁住的是 lock1 对象实例,demo2 方法中的同步代码块锁住的是 lock2 对象实例

如果线程 1 执行 demo1,线程 2 执行 demo2,由于两个方法抢占的是不同的对象实例锁,也就是说两个线程均能获取到锁执行各自的方法。