Java中synchronized同步锁作用范围的对比

假设ClassA类中有非静态方法methodA/methodB,
现有ClassA的实例cla, 
线程t1/t2 

对象锁

  对象锁
加在非静态方法,或对象实例上

结论

 

2个线程同时访问,
cla的synchronized methodA方法

cla的methodA方法中的synchronized  代码块
2个线程顺序访问,一个线程执行完,另一个线程才能执行 当线程 t1 调用某对象的synchronized 方法 或者 synchronized 代码块时,若同步锁未释放,
其他线程调用同一对象的synchronized 方法 或者 synchronized 代码块时将被阻塞,
直至线程 t1 释放该对象的同步锁。
线程t1访问cla的synchronized methodA 或 methodA中的synchronized 代码块,
线程t2访问cla的synchronized methodB 或 methodB中的synchronized 代码块
2个线程顺序访问,一个线程执行完,另一个线程才能执行 当线程 t1 调用某对象的synchronized 方法 或者 synchronized 代码块时,若同步锁未释放,
其他线程调用同一对象的其他synchronized 方法 或者 synchronized 代码块时将被阻塞,
直至线程 t1 释放该对象的同步锁。(注意:重点是其他)
线程t1访问cla的synchronized methodA,
线程t2访问cla的methodB(非同步方法)
2个线程交叉访问,无序 当线程 t1 调用某对象的synchronized 方法 或者 synchronized 代码块时,无论同步锁是否释放,
其他线程调用同一对象的其他 非 synchronized 方法 或者 非 synchronized 代码块时可立即调用
ClassA的不同实例cla1,cla2
t1访问cla1的synchronized  methodA方法
t2访问cla2的synchronized  methodA方法
2个线程交叉访问,无序 不同的实例,持有不同的锁,互不影响,可以同时访问

 

类锁 

  类锁
加在类或静态方法上
结论
public static synchronized void methodA() {}
线程t1/t2同时访问methodA
2个线程顺序访问,一个线程执行完,另一个线程才能执行 静态方法是类所有对象共用的,所以进行同步后,该静态方法的锁也是所有对象唯一的。
每次只能有一个线程来访问对象的该非静态同步方法。 
public static synchronized void methodA() {}
public static synchronized void methodB() {}
线程t1访问methodA
线程t2访问methodB
2个线程顺序访问,一个线程执行完,另一个线程才能执行 类锁是全局的,每次只能有一个线程来访问对象的该非静态同步方法。 
public static synchronized void methodA() {}
public synchronized void methodB() {}
线程t1访问methodA
线程t2访问cla实例的methodB
2个线程交叉访问,无序 类锁和对象锁是不一样的锁,是互相独立的
public static synchronized void methodA() {}
public void methodB() {}
线程t1访问methodA
线程t2访问methodB
2个线程交叉访问,无序 同步方法和非同步方法互不影响,可以同时访问

上面的表格排版不好,再放个截图

Java中synchronized同步锁作用范围的对比