ReentrantLock的三种获取锁Lock,tryLock,lockInterruptibly的区别

您所在的位置:网站首页 获取和攫取的区别 ReentrantLock的三种获取锁Lock,tryLock,lockInterruptibly的区别

ReentrantLock的三种获取锁Lock,tryLock,lockInterruptibly的区别

2024-07-09 13:19| 来源: 网络整理| 查看: 265

重入锁有三种获取锁的方式,本文就是来说明三种方式的异同点的.

lock public void lock()

获得锁。

如果锁没有被另一个线程占用并且立即返回,则将锁定计数设置为1。如果当前线程已经保持锁定,则保持计数增加1,该方法立即返回。如果锁被另一个线程保持,则当前线程将被禁用以进行线程调度,并且在锁定已被获取之前处于休眠状态,此时锁定保持计数被设置为1。 tryLock boolean tryLock(); 当获取锁时,只有当该锁资源没有被其他线程持有才可以获取到,并且返回true,同时设置持有count为1。当获取锁时,当前线程已持有该锁,那么锁可用时,返回true,同时设置持有count加1。当获取锁时,如果其他线程持有该锁,无可用锁资源,直接返回false,这时候线程不用阻塞等待,可以先去做其他事情。即使该锁是公平锁fairLock,使用tryLock()的方式获取锁也会是非公平的方式,只要获取锁时该锁可用那么就会直接获取并返回true。这种直接插入的特性在一些特定场景是很有用的。但是如果就是想使用公平的方式的话,可以试一试tryLock(0,TimeUnit.SECONDS),几乎跟公平锁没区别,只是会监测中断事件

使用标准模板:

Lock lock = ...; if (lock.tryLock()) { try { // manipulate protected state } finally { lock.unlock(); } } else { // perform alternative actions }

tryLock的重载方法:

boolean tryLock(long time, TimeUnit unit) throws InterruptedException; 获取锁成功或者超时之后返回。而且在公平锁和非公平锁的场景下都可以使用,只是会增加对中断事件的监测。当获取锁时,锁资源在超时时间之内变为可用,并且在等待时没有被中断,那么当前线程成功获取锁,返回true,同时当前线程持有锁的count设置为1.当获取锁时,在超时时间之内没有锁资源可用,那么当前线程获取失败,不再继续等待,返回false.当获取锁时,在超时等待时间之内,被中断了,那么抛出InterruptedException,不再继续等待.当获取锁时,在超时时间之内锁可用,并且当前线程之前已持有该锁,那么成功获取锁,同时持有count加1. lockInterruptibly void lockInterruptibly() throws InterruptedException;     当获取锁时,锁资源可用,那么当前线程成功获得锁,同时持有count设置为1,返回true.    当获取锁时,锁资源可用,当前线程已持有该锁,它成功获取该锁,同时持有count增加1,返回true.    当获取锁时,锁资源不可用,那么该线程开始阻塞休眠等待,但是等待过程中如果有中断事件,那么会停止等待,立即返回.    当获取锁时,锁资源不可用,线程开始阻塞休眠等待,如果等待过程中锁资源变为可用,那么当前线程成功获得锁,同时持有count设置为1,返回true.

lockInterruptibly()获取锁是以排他的模式获取,一旦被中断就放弃等待获取。在等待开始时首先检测中断状态,然后至少调用一次tryAcquire,成功获取就返回true。否则当前线程就开始排队,并且不断的被blocking、unblocking、invoking tryAcquire 直到获取成功或者被中断为止。

下面使用代码进行演示:

package com.springcloud.server.springserver.thread; import java.util.concurrent.locks.ReentrantLock; public class TestLockAndTryLock { private ReentrantLock rlock = new ReentrantLock(); private void lockTest(){ long currentTime = System.currentTimeMillis(); try { rlock.lock(); while (System.currentTimeMillis() - currentTime lockAndTryLock.tryLockTest(), "TryLock-Thread" ); tryLockThread.start(); lockThread.start(); } }

 输出结果:

lock()方法先获取锁,然后在执行任务的时候阻塞,tryLock()会在尝试加锁失败的时候返回false. package com.springcloud.server.springserver.thread; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; public class TestLockAndTryLock1 { private ReentrantLock rlock = new ReentrantLock(); private void lockTest(){ long currentTime = System.currentTimeMillis(); try { rlock.lock(); System.out.println("lockTest----current thread get the lock: " + Thread.currentThread().getName()); while (System.currentTimeMillis() - currentTime lockAndTryLock.tryLockInterruptTest(), "TryLockInterrupt-Thread" ); tryLockInterruptThread.start(); lockThread.start(); } }

 输出结果:

lock()方法先获取锁,然后执行任务5秒,tryLock()方法先直接获取锁,获取不到就在1秒的时间内持续获取锁,超过时间还获取不到就返回false. package com.springcloud.server.springserver.thread; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; public class TestLockAndTryLock2 { private ReentrantLock rlock = new ReentrantLock(); private void lockTest(){ long currentTime = System.currentTimeMillis(); try { rlock.lock(); System.out.println("lockTest----current thread get the lock: " + Thread.currentThread().getName()); while (System.currentTimeMillis() - currentTime lockAndTryLock.tryLockInterruptTest(), "TryLockInterrupt-Thread" ); tryLockInterruptThread.start(); lockThread.start(); try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + "is interrupted now. "); } tryLockInterruptThread.interrupt(); } }

lock()方法先获取锁,然后执行任务5秒,tryLock()方法先直接获取锁,获取不到就在1秒的时间内持续获取锁,在获取锁的过程中,主线程(main)以通知的方式中断tryLockInterruptThread线程,tryLock()方法可以响应中断.

package com.springcloud.server.springserver.thread; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class TestLockInterruptibly { final Lock lock = new ReentrantLock(); public static void main(String[] args) throws Exception { TestLockInterruptibly testLockInterruptibly = new TestLockInterruptibly(); Thread lockThread = new Thread( () -> testLockInterruptibly.lock() ); Thread interruptiblyThread = new Thread( () -> testLockInterruptibly.lockInterruptibly() ); lockThread.start(); interruptiblyThread.start(); TimeUnit.SECONDS.sleep(2); // interruptiblyThread.interrupt(); } public void lockInterruptibly() { long currentTime = System.currentTimeMillis(); while (System.currentTimeMillis() - currentTime


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3