synchronized原理可以参考此篇文章
一、ReentrantLock与synchronized的比较
- 共同点
- 二者都属于可重入锁、独占锁(即不同线程之间的访问是互斥的)
- 不同点
- synchronized加锁与解锁是隐试的ReentrantLock是显示的
- synchronized不可响应中断,一个线程获取不到锁就一直等着,ReentrantLock可以相应中断(使用
lockInterruptibly()
方法加锁) - synchronized是非公平锁,ReentrantLock可以通过过程函数传入参数指定锁是否是公平锁,所谓公平锁就是谁等待时间长谁先获取锁,非公平锁就线程之间自由竞争随机占用锁
- ReentrantLock有尝试获取锁的方法
tryLock()
- 锁处于空闲:返回true,将锁持有者设置为1
- 当前线程持有锁(可重入锁):返回true,同时将锁持有者加1
- 其他线程持有锁:返回false
public class MyReentrantLock {
private static ReentrantLock lock1 = new ReentrantLock();
private static ReentrantLock lock2 = new ReentrantLock();
public static void main(String[] args) {
new Thread(()->{
lock1.lock();
},"Thread-1").start();
new Thread(()->{
boolean b = lock1.tryLock();
System.out.println(b);
},"Thread-2").start();
new Thread(()->{
lock2.lock();
boolean b = lock2.tryLock();
System.out.println(b);
},"Thread-3").start();
}
}
二、关于ReentrantLock需要注意的点
- 释放锁的操作务必放在finally代码块里
- 由于ReentrantLock是可重入锁,因此要特别注意加锁与释放锁的次数要一直
public class MyReentrantLock {
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock(true);
lock.lock();
try {
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}