Synchronized 到底锁了谁
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,由于两个方法抢占的是不同的对象实例锁,也就是说两个线程均能获取到锁执行各自的方法。