假设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个线程交叉访问,无序 | 同步方法和非同步方法互不影响,可以同时访问 |
上面的表格排版不好,再放个截图