tryLock
和 lock
是 Java 中用于线程同步的两个方法,主要用于控制对共享资源的访问,它们在具体使用方式和行为上有一些重要区别。
lock
方法
lock
方法来自于 java.util.concurrent.locks.Lock
接口,用于获取锁。如果锁已经被其他线程持有,调用 lock
方法的线程将被阻塞,直到获取到锁为止。
特点:
- 阻塞行为:如果锁不可用,线程会一直等待,直到获取到锁。
- 适用场景:适用于需要确保获取锁的场景,并且可以容忍线程被阻塞的情况。
示例代码:
Lock lock = new ReentrantLock();
lock.lock(); // 阻塞直到获得锁
try {
// 访问共享资源
} finally {
lock.unlock(); // 确保锁最终被释放
}
tryLock
方法
tryLock
方法同样来自于 java.util.concurrent.locks.Lock
接口,用于尝试获取锁。如果锁不可用,tryLock
方法不会阻塞线程,而是立即返回一个布尔值,指示锁是否获取成功。
特点:
- 非阻塞行为:如果锁不可用,
tryLock
方法会立即返回false
,而不是阻塞线程。 - 超时机制:
tryLock
方法可以接受一个超时时间参数,指定在尝试获取锁时等待多长时间。 - 适用场景:适用于需要尝试获取锁,但不希望被长期阻塞的场景,例如需要在锁不可用时执行其他操作。
示例代码:
无超时参数的 tryLock
:
Lock lock = new ReentrantLock();
if (lock.tryLock()) { // 尝试获取锁,如果失败立即返回
try {
// 访问共享资源
} finally {
lock.unlock();
}
} else {
// 执行其他操作
}
带超时参数的 tryLock
:
Lock lock = new ReentrantLock();
try {
if (lock.tryLock(1, TimeUnit.SECONDS)) { // 尝试获取锁,最多等待1秒
try {
// 访问共享资源
} finally {
lock.unlock();
}
} else {
// 执行其他操作
}
} catch (InterruptedException e) {
// 处理中断
}
区别总结
阻塞行为:
lock
方法是阻塞的,如果锁不可用,调用线程会一直等待直到获得锁。tryLock
方法是非阻塞的,如果锁不可用,它会立即返回一个布尔值,指示锁是否获取成功。
灵活性:
lock
方法适合在必须获取锁的情况下使用,不考虑获取锁的时间长短。tryLock
方法提供了更大的灵活性,可以立即返回结果,也可以指定超时时间,适合在需要非阻塞获取锁的情况下使用。
使用场景:
lock
适用于需要确保访问共享资源,并且能够容忍阻塞的情况。tryLock
适用于需要尝试获取锁,但不希望线程被阻塞的情况,例如需要在锁不可用时执行其他操作或在某个时间段内获取锁。