synchronized 是 Java 语言中处理并发问题的一种常用手段,它也被我们亲切的称之为“Java 内置锁”,由此可见其地位之高。然而 synchronized 却有着多种用法,当它修饰不同对象时,其意义也是不同的,下面我们一起来看。
synchronized 用法
synchronized 可以用来修饰普通方法、静态方法和代码块。
① 修饰普通方法
/** * synchronized 修饰普通方法 */ public synchronized void method() { // ....... }
当 synchronized 修饰普通方法时,被修饰的方法被称为同步方法,其作用范围是整个方法,作用的对象是调用这个方法的对象。
② 修饰静态方法
/** * synchronized 修饰静态方法 */ public static synchronized void staticMethod() { // ....... }
当 synchronized 修饰静态的方法时,其作用的范围是整个方法,作用对象是调用这个类的所有对象。
③ 修饰代码块
为了减少锁的粒度,我们可以选择在一个方法中的某个部分使用 synchronized 来修饰(一段代码块),从而实现对一个方法中的部分代码进行加锁,实现代码如下:
public void classMethod() throws InterruptedException { // 前置代码... // 加锁代码 synchronized (SynchronizedExample.class) { // ...... } // 后置代码... }
以上代码在执行时,被修饰的代码块称为同步语句块,其作用范围是大括号“{}”括起来的代码块,作用的对象是调用这个代码块的对象。
但以上代码,除了可以加锁 class 之外,还可以加锁 this,具体示例如下:
public void classMethod() throws InterruptedException { // 前置处理代码... synchronized (this) { // ...... } // 后置处理代码... }
那问题来了,使用 synchronized 加锁 this 和 class 的区别是什么?不都是加锁同一个类吗?
答案还真不是,加锁 this 和 class 区别还是很大的。下面我们通过以下 4 个示例,来看二者之间的区别。