深入理解 Lock 接口:lock()、tryLock()、lockInterruptibly() 的区别
2023-09-11 12:36:41
在 Java 的并发编程中,Lock 接口是实现线程同步的重要工具之一。它提供了四种获取锁的方法:lock()、tryLock()、lockInterruptibly() 和 newCondition()。其中,lock()、tryLock() 和 lockInterruptibly() 这三个方法都用于获取锁,但它们在行为和适用场景上存在差异。本文将深入剖析这三个方法的区别,帮助您更好地理解和使用它们。
lock()
lock() 方法是 Lock 接口中最基础的获取锁的方法。它会一直阻塞当前线程,直到获取到锁为止。如果在获取锁的过程中发生了中断,则会抛出 InterruptedException 异常。
public void lock() throws InterruptedException {
acquire(1);
}
tryLock()
tryLock() 方法尝试获取锁,但它不会阻塞当前线程。如果在获取锁时锁已经被其他线程持有,则方法立即返回 false。如果成功获取到锁,则方法返回 true。
public boolean tryLock() {
return acquire(0);
}
lockInterruptibly()
lockInterruptibly() 方法与 lock() 方法类似,都会阻塞当前线程直到获取到锁。但是,lockInterruptibly() 方法在等待获取锁的过程中是可中断的。如果在获取锁的过程中发生了中断,则会抛出 InterruptedException 异常。
public void lockInterruptibly() throws InterruptedException {
acquireInterruptibly(1);
}
区别与应用场景
lock() 与 tryLock()
- lock(): 会一直阻塞当前线程,直到获取到锁为止,在高并发场景下可能导致线程长时间阻塞,降低系统吞吐量。
- tryLock(): 不会阻塞当前线程,尝试获取锁失败时会立即返回,适用于对锁竞争不激烈的场景,可以提高系统的吞吐量。
lock() 与 lockInterruptibly()
- lock(): 在获取锁的过程中不可中断,如果线程被中断,则会抛出 InterruptedException 异常,适用于对锁竞争激烈的场景,可以确保线程能够获取到锁。
- lockInterruptibly(): 在获取锁的过程中可中断,如果线程被中断,则会抛出 InterruptedException 异常,适用于对锁竞争不激烈的场景,并且需要对线程中断做出响应。
总结
Java Lock 接口中的 lock()、tryLock() 和 lockInterruptibly() 这三个方法都是用于获取锁,但它们在行为和适用场景上存在差异。lock() 方法会一直阻塞当前线程,直到获取到锁为止;tryLock() 方法尝试获取锁,但不会阻塞当前线程;lockInterruptibly() 方法与 lock() 方法类似,都会阻塞当前线程直到获取到锁,但它是可中断的。开发者需要根据具体的场景选择合适的方法来获取锁。