ReentrantLock的介绍及其用法
Reentrantlock默认是非公平锁
private static ReentrantLock lock = new ReentrantLock();
若想实现公平锁,只需使用重载构造器,fair参数传入true
private static ReentrantLock lock = new ReentrantLock(true);
公平锁会按照线程
请求锁的顺序进行获取,遵循先到先得的原则。而非公平锁则没有这种保证,允许新的线程在旧线程之前获取到锁。在大多数情况下,非公平锁的性能更好,因为它允许新的线程立即获取锁,而不需要等待。
如果是公平锁,会先检查AQS队列中是否存在线程在排队,如果有线程在排队,则当前线程也进行排队
如果是非公平锁,则不会去检查是否有线程在排队,而是直接竞争锁
lock()
方法
Thread t1 = new Thread(() -> {
lock.lock();
try {
System.out.println("Thread 1 acquired the lock");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println("Thread 1 released the lock");
}
});
lockInterruptibly()
方法,线程通过此方法获取锁时,线程在执行任务的过程中允许被打断,释放锁并抛出InterruptedException异常
Thread t1 = new Thread(() -> {
try {
lock.lockInterruptibly();
try {
System.out.println("Thread 1 acquired the lock");
Thread.sleep(5000);
} finally {
lock.unlock();
System.out.println("Thread 1 released the lock");
}
} catch (InterruptedException e) {
System.out.println("Thread 1 was interrupted while waiting for the lock");
}
});
Thread t2 = new Thread(() -> {
// 让线程2休眠一段时间后打断线程1
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t1.interrupt(); // 中断线程1的等待
});
tryLock()
方法,尝试获取锁,获取到锁执行逻辑一,没有获取到锁执行逻辑二
Thread t1 = new Thread(() -> {
try {
if (lock.tryLock(5, TimeUnit.SECONDS)) {
try {
System.out.println("Thread 1 acquired the lock");
Thread.sleep(1000);
} finally {
lock.unlock();
System.out.println("Thread 1 released the lock");
}
} else {
System.out.println("Thread 1 failed to acquire the lock");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
anyway,这些获取锁的方法,最后都需要调用unlock()
方法释放锁,否则其他线程将无法获取锁,从而导致死锁