Synchronized 关键字,用于锁定一个共享可变的资源。当一个线程需要使用该类资源时,需要检查其是否被其它线程占用,如果有其它线程正在使用该资源,则需要等其它线程释放后,当前线程才能调用。
简而言之,被 synchronized 修饰的一段逻辑将会成为一个同步块,在任何时间内都只允许一个线程访问。
加锁的层次
1. 对象锁
每个对象都有各自的锁,互不影响
平常所说的类锁,是一种特殊的对象锁。
2. 方法锁
1)修饰普通方法,锁对象默认为当前实例
public synchronized void method() {
……
}
2) 修饰 static 方法,锁对象为当前类
public static synchronized void classLock() {
……
}
无论方法正常执行完还是抛出异常,都会释放锁
3. 代码块锁
示例代码如下:
public void method() {
Object o = new Object();
synchronized (o) {
……
}
}
当一个线程访问对象的一个被 synchronized(this) 修饰的代码块时,其它线程对该对象中其它 synchronized(this) 修饰的代码块的访问将被阻塞。
当一个线程访问一个对象中的一个加锁代码块时,其它线程可以访问非加锁的代码部分。
Synchronized 原理
Java 内部使用监视器锁(或称内部锁)来提供同步,这些监视器绑定到一个对象,以此保证所有对象的所有同步块只能有一个线程访问它们。
注意事项
- 锁对象不能为空,因为锁信息都保存在对象头里;
- 作用域不宜过大,会影响程序执行速度;
- Synchronized 时非公平的,可能会导致饥饿现象;
参考: