目录
synchronized和ReentrantLock两种锁的区别
synchronized
实现描述: 当一个线程进入synchronized代码块时,会尝试获取锁。如果锁没有被其他线程占用,则获取锁成功,该线程可以执行代码块中的逻辑。当线程执行完代码块后,会释放锁,以供其他线程获取。
public class Counter {
private int count;
public void add(int n) {
synchronized(this) {
count += n;
}
}
}
ReentrantLock
ReentrantLock使用的是显示锁(也称为可重入锁)的机制,它允许线程在获取锁之后再次获取同一个锁,并且支持将锁的获取与释放分开控制。
public class Counter {
private final Lock lock = new ReentrantLock();
private int count;
public void add(int n) {
lock.lock();
try {
count += n;
} finally {
lock.unlock();
}
}
}
ReentrantLock尝试获取锁
public class ReentrantLockExample {
private ReentrantLock lock = new ReentrantLock();
public void doSomething() {
if (lock.tryLock()) {
try {
// 成功获取锁后执行的代码逻辑
System.out.println(Thread.currentThread().getName() + "ok");
// 执行其他业务逻辑
} finally {
lock.unlock();
}
} else {
// 未成功获取锁时的处理逻辑
System.out.println(Thread.currentThread().getName() + "no");
// 可以选择等待一段时间后重新尝试获取锁,或者执行其他业务逻辑
}
}
}
synchronized和ReentrantLock两种锁的区别
相同点
- 目的:synchronized和ReentrantLock都是为了实现线程之间的同步,保证多个线程对共享资源的安全访问。
- 实现原理:它们都采用了独占锁(互斥锁)的机制,同一时间只允许一个线程访问被锁保护的代码块或方法。
不同点
- 锁的获取方式不同:synchronized是隐式锁,即在进入同步代码块或方法时自动获取锁,退出时自动释放锁;而reentrantlock是显式锁,需要手动获取和释放锁。
- 可重入性不同:synchronized是可重入锁,即同一个线程可以多次获取同一把锁,而reentrantlock也是可重入锁,但需要手动实现。
- 等待可中断性不同:synchronized不支持等待可中断,即线程无法响应中断请求,而reentrantlock支持等待可中断,可以响应中断请求。
- 公平性不同:synchronized是非公平锁,即无法保证等待时间最长的线程最先获取锁,而reentrantlock可以通过构造函数指定是否为公平锁。
- 性能不同:在低并发情况下,synchronized的性能优于reentrantlock,但在高并发情况下,reentrantlock的性能优于synchronized。