介绍
Java中的synchronized
关键字是一种内置的同步机制,用于实现线程之间的互斥,以确保多个线程在同一时刻只能有一个线程访问特定的代码段或对象。synchronized
可以用于方法或代码块,从而实现对共享资源的安全访问。
前言
需要明确的是,锁是针对对象而言的,以下场景实际上都是在描述外在表现,内部实现请细究jvm原理。现在,用一句话来概括以下场景,线程只有拿到对象的锁,才能对锁住的代码块进行访问。
使用场景
-
修饰具体对象:
- synchronized(this){}
- synchronized (object){}
- 在以上两种情况下,锁住的范围是{}之间,需要拿到()中的这个对象的锁,才能访问{}之间的代码体。
- 由于每一个类都对应着一个Class对象,也可以这么写:synchronized(类名.class) {}
- 一个有意思的实现
- 当没有明确的对象,仅仅想让一段代码同步,创建一个节省的对象来充当锁:private byte[] lock = new byte[0];
-
成员方法(非静态):
- 在方法的前面加synchronized 如,public synchronized void
- 现在,代指当前方法为方法A,在以上情况下,锁住的范围是当前方法的方法体,需要拿到当前对象的锁,才能访问当前对象的方法A。即,成员方法是归属于特定对象的,拿到该对象(或者说实例)的锁,能访问该对象从属的方法A的方法体,但是该类的不同对象而言,访问每个对象里的该方法,都需要当前对象的锁。
-
修饰静态方法:
- public synchronized static void method()
- 静态方法是属于类的而不属于对象的。同样的,当使用 synchronized 修饰静态方法时,锁住的是该类的类对象(Class object),而不是具体的实例对象,这意味着所有该类的静态方法将共享同一个锁,而不管它们是被哪个实例调用的,该实例都要拿到该类的类对象的锁。
后记
待补充jvm知识
参考文章
https://blog.csdn.net/luoweifu/article/details/46613015
https://www.cnblogs.com/lifegoeson/p/13683785.html