synchronized是Java中的关键字,是一种同步锁,保证某些“东西”同一时间只能有一个“人”能够“接触”到,它修饰的对象有下文几种。
修饰一个代码块,被修饰的代码块称为同步语句块,同步句块的范围是大括号{}括起来的代码, 锁的范围根据synchronized(“东西”){ xxxxxxxxxx }的括号中的“东西”来定,可以是this、类、变量/具体的实例,比如: class 人{ public static String 筷子="筷子"; //如果是这个,那么说明每个人的实例只能一顿一顿吃,不能同时(多线程)吃好几顿饭。 synchronized(this){ 吃饭(); } //如果是这个,那么只要整个人类有一个人在吃饭,其他所有人都不能吃饭,得等那个正在吃饭的人吃完。 synchronized(人.class){ 吃饭(); } //取得筷子权限才可以吃饭,被synchronized(筷子)修饰的代码块是互斥的 synchronized(筷子){ 吃饭(); } } 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是这个方法依附的实例对象; public synchronized void method() { // todo }完全等价于下面的写法,和“补充”中的第一条相符!并且更推荐此种方法,效率更高。
public void method() { synchronized(this) { // todo } } 修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象; public synchronized static void method() { // todo }在都只是用来修饰某个方法的情况下,synchronized是对类的当前的这个实例进行加锁,防止其他线程同时访问这个实例的所有synchronized块,这个实例的所有synchronized块同时只有一部分是能被访问的。 static synchronized是限制线程同时访问jvm中该类的所有实例同时访问对应的代码块,同理,这个类的所有static synchronized块同时只有一部分是能被访问的。 综上:synchronized和static synchronized是两把毫不相干的锁,并且会对其他同类型的加锁区域互斥。 例子如下:
pulbic class Something(){ //某一个实例的方法锁 public synchronized void isSyncA(){} public synchronized void isSyncB(){} //类的静态方法锁 public static synchronized void cSyncA(){} public static synchronized void cSyncB(){} }注:该列子出自-结成浩的《java多线程设计模式》 假设有Something类的两个实例x与y,那么分析下面的调用情况:
x.isSyncA()与x.isSyncB() 不能同时执行这个语句,同一个实例的同步方法是互斥
x.isSyncA()与y.isSyncA() 可以同时执行,不同实例的同步方法毫不关系,在内存里八竿子打不着
x.cSyncA()与y.cSyncB() 不能同时执行,同一个类的静态锁方法是互斥的
x.isSyncA()与Something.cSyncA() 可以同时执行,不通类型(static和非static)的锁,毫无关系
参考文章:Java中Synchronized的用法 https://blog.csdn.net/luoweifu/article/details/46613015