Java 线程互斥同步 Synchronized与ReentrantLock
Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问
- JVM 实现的 synchronized
- JDK 实现的 ReentrantLock
作用
当一个线程进入同步语句块时,另一个线程就必须等待
Synchronized使用
// synchronized用在代码块中使用
public void func() {
synchronized (this) {
// 业务逻辑
}
}
// synchronized用在普通方法上,默认的锁就是this,当前实例
public synchronized void method() {
// 业务逻辑
}
// synchronized用在静态方法上,默认的锁就是当前所在的Class类,所以无论是哪个线程访问它,需要的锁都只有一把
public static synchronized void method() {
// 业务逻辑
}
ReentrantLock使用
public class Example{
// 创建锁
private Lock lock = new ReentrantLock();
public void func() {
// 锁住
lock.lock();
try {
// 业务逻辑
} finally {
// 确保释放锁,从而避免发生死锁。
lock.unlock();
}
}
}
对比
1. 锁的实现
synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的。
2. 性能
新版本 Java 对 synchronized 进行了很多优化,例如自旋锁等,synchronized 与 ReentrantLock 大致相同。
3. 等待中断
当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。
ReentrantLock 可中断,而 synchronized 不行。