synchronized 是 Java 中的关键字,是一种同步锁。它修饰的对象有以下几种:
- 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号 {} 括起来的代码,作用的对象是调用这个代码块的对象
- 修饰一个实例方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象
- 修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象
- 修饰一个类,其作用的范围是 synchronized 后面括号括起来的部分,作用的对象是这个类的所有对象
synchronized (this) 代码块的作用和 synchronized 方法的作用一样
synchronized (class) 代码块的作用和 synchronized static 方法的作用一样
synchronized 方法锁定的是整个方法,相对与 synchronized 代码块来说效率较低:
如果一个方法被 synchronized 修饰,则方法内的所有步骤都是同步的,甚至连不需要同步的步骤也必须同步执行。如果用 synchronized(object) 的话,当一个线程访问方法内的 synchronized(object) 时,另一个线程仍然可以执行方法内的非 synchronized(object) 步骤
关键字 synchronized 具有锁重入的功能,也就是在使用 synchronized 时,当一个线程得到一个对象锁后,再次请求此对象锁是可以再次得到该对象锁的。这样证明在一个 synchronized 方法 / 块的内部调用本类的其他 synchronized 方法 / 块时,是永远可以得到锁的。如果不可锁重入的话,就会造成死锁
当一个线程执行的代码出现异常时,其所持有的锁会自动释放
synchronized 不具有继承性:即子类重写父类的 synchronized 方法后,如果子类的方法不带有 synchronized 关键字,则子类方法不是同步的。当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。这时子类调用的 super.synchronizedMethod() 拿的是父类对象的锁