在 Lock 接口中,获取锁的办法有 4 个:lock()、tryLock()、tryLock(long,TimeUnit)、lockInterruptibly(),为什么须要这么多办法?这些办法都有什么区别?接下来咱们一起来看。
lock 办法
lock 办法是 Lock 接口中最根底的获取锁的办法,当有可用锁时会间接失去锁并立刻返回,当没有可用锁时会始终期待,直到获取到锁为止,它的根底用法如下:
Lock lock = new ReentrantLock();// 获取锁lock.lock();try { // 执行业务代码...} finally { //开释锁 lock.unlock(); }
lockInterruptibly 办法
lockInterruptibly 办法和 lock 办法相似,当有可用锁时会间接失去锁并立刻返回,如果没有可用锁会始终期待直到获取锁,但和 lock 办法不同,lockInterruptibly 办法在期待获取时,如果遇到线程中断会放弃获取锁。它的根底用法如下:
Lock lock = new ReentrantLock();try { // 获取锁 lock.lockInterruptibly(); try { // 执行业务办法... } finally { // 开释锁 lock.unlock(); }} catch (InterruptedException e) { e.printStackTrace();}
PS:应用 thread.interrupt() 办法能够中断线程执行。
tryLock 办法
与后面的两个办法不同,应用无参的 tryLock 办法会尝试获取锁,并立刻返回获取锁的后果(true 或 false),如果有可用锁返回 true,并失去此锁,如果没有可用锁会立刻返回 false。它的根底用法如下:
Lock lock = new ReentrantLock();// 获取锁boolean result = lock.tryLock();if (result) { try { // 获取锁胜利,执行业务代码... } finally { // 开释锁 lock.unlock(); }} else { // 执行获取锁失败的业务代码...}
tryLock(long,TimeUnit) 办法
有参数的 tryLock(long,TimeUnit) 办法须要设置两个参数,第一个参数是 long 类型的超时工夫,第二个参数是对参数一的工夫类型形容(比方第一参数是 3,那么它到底是 3 秒还是 3 分钟,是第二个参数说了算的)。在这段时间内如果获取到可用的锁了就返回 true,如果在定义的工夫内,没有失去锁就会返回 false。它的根底用法如下:
Lock lock = new ReentrantLock();try { // 获取锁(最多期待 3s,如果获取不到锁就返回 false) boolean result = lock.tryLock(3, TimeUnit.SECONDS); if (result) { try { // 获取锁胜利,执行业务代码... } finally { // 开释锁 lock.unlock(); } } else { // 执行获取锁失败的业务代码... }} catch (InterruptedException e) { e.printStackTrace();}
总结
lock()、tryLock()、tryLock(long,TimeUnit)、lockInterruptibly() 都是用来获取锁的,其中 lock 办法如果获取不到锁会始终阻塞期待;而 lockInterruptibly 办法尽管也会阻塞期待获取锁,但它却能中途响应线程的中断;无参的 tryLock 办法会立马返回一个获取锁胜利与失败的后果,有参数的 tryLock(long,TimeUnit) 办法会在设定的工夫内返回一个获取锁胜利与失败的后果。这 4 个办法的个性各不相同,须要依据理论的业务状况抉择适合获取锁的办法。
是非审之于己,毁誉听之于人,得失安之于数。
公众号:Java面试真题解析
面试合集:https://gitee.com/mydb/interview