下面的文章内容要给大家介绍的就是java当中的reentrantlock,主要介绍了reentrantlock的概念以及适用,一起来了解一下吧。
reentrantlock概念和使用
可重入锁也被叫做递归锁,指的是同一线程外层函数获得锁之后 ,内层递归函数仍然有获取这个锁的代码,但不受影响,在JAVA当中,ReentrantLock以及synchronized都是可重入锁。
ReentrantLock在Java也是一个基础的锁,ReentrantLock实现Lock接口提供一系列的基础函数,开发人员可以灵活的是应用函数满足各种复杂多变应用场景。
(1)Lock接口:
Java中的ReentrantLock也是实现了Java中锁的核心接口Lock。
在Lock接口定义了标准函数,可是,具体实现是在实体类中[类似list和arrayList、linkedList关系]。
//获取锁,获取不到lock就不罢休,不可被打断,即使当前线程被中断,线程也一直阻塞,直到拿到锁, 比较无赖的做法。 void lock(); /** *获取锁,可中断,如果获取锁之前当前线程被interrupt了, *获取锁之后会抛出InterruptedException,并且停止当前线程; *优先响应中断 */ void lockInterruptibly() throws InterruptedException; //立即返回结果;尝试获得锁,如果获得锁立即返回ture,失败立即返回false boolean tryLock(); //尝试拿锁,可设置超时时间,超时返回false,即过时不候 boolean tryLock(long time, TimeUnit unit) throws InterruptedException; //释放锁 void unlock(); //返回当前线程的Condition ,可多次调用 Condition newCondition();
(2)ReentrantLock私有public方法(ReentrantLock中除了实现Lock中定义的一些标准函数外,同时提供其他的用于管理锁的public方法)。
//传入boolean值,true时create一个公平锁,false为非公平锁 ReentrantLock(boolean fair) //查看有多少线程等待锁 int getQueueLength() //是否有线程等待抢锁 boolean hasQueuedThreads() //是否有指定线程等待抢锁 boolean hasQueuedThread(Thread thread) //当前线程是否抢到锁。返回0代表没有 int getHoldCount() //查询此锁是否由任何线程持有 boolean isLocked() //是否为公平锁 boolean isFair()
(3)ReentrantLock中Condition的使用
ReentrantLock中另一个重要的应用就是Condition,Condition是Lock上的一个条件,可以多次newCondition()获得多个条件,Condition可用于线程间通信,通过Condition能够更加精细的控制多线程的休眠与唤醒,而且在粒度和性能上都优于Object的通信方法(wait、notify 和 notifyAll);
还是先来看一下Condition 接口的源码吧:
public interface Condition { /** *Condition线程进入阻塞状态,调用signal()或者signalAll()再次唤醒, *允许中断如果在阻塞时锁持有线程中断,会抛出异常; *重要一点是:在当前持有Lock的线程中,当外部调用会await()后,ReentrantLock就允许其他线程来抢夺锁当前锁, *注意:通过创建Condition对象来使线程wait,必须先执行lock.lock方法获得锁 */ void await() throws InterruptedException; //Condition线程进入阻塞状态,调用signal()或者signalAll()再次唤醒,不允许中断,如果在阻塞时锁持有线程中断,继续等待唤醒 void awaitUninterruptibly(); //设置阻塞时间,超时继续,超时时间单位为纳秒,其他同await();返回时间大于零,表示是被唤醒,等待时间并且可以作为等待时间期望值,小于零表示超时 long awaitNanos(long nanosTimeout) throws InterruptedException; //类似awaitNanos(long nanosTimeout);返回值:被唤醒true,超时false boolean await(long time, TimeUnit unit) throws InterruptedException; //类似await(long time, TimeUnit unit) boolean awaitUntil(Date deadline) throws InterruptedException; //唤醒指定线程 void signal(); //唤醒全部线程 void signalAll(); }
ReentrantLock.Condition的线程通信:
ReentrantLock.Condition是在粒度和性能上都优于Object的notify()、wait()、notifyAll()线程通信的方式。
Condition中通信方法相对Object的通信在粒度上是粒度更细化,表现在一个Lock对象上引入多个Condition监视器、通信方法中除了和Object对应的三个基本函数外,更是新增了线程中断、阻塞超时的函数;
Condition中通信方法相对Object的通信在性能上更高效,性能的优化表现在ReentrantLock比较synchronized的优化 ;
基本示例代码:
多线程通信/同步的一个经典的应用属于**生产者消费者模式**,关于通过ReentrantLock的newCondition()是实现生产者消费者模式可以直接参考: 生产者消费者模式 ;
ReentrantLock.Condition线程通信注意点:
1.使用**ReentrantLock.Condition的signal()、await()、signalAll()方法使用之前必须要先进行lock()操作**[记得unlock()],类似使用Object的notify()、wait()、notifyAll()之前必须要对Object对象进行synchronized操作;否则就会抛IllegalMonitorStateException;
2.注意在使用**ReentrantLock.Condition中使用signal()、await()、signalAll()方法,不能和Object的notify()、wait()、notifyAll()方法混用,否则抛出IllegalMonitorStateException`;
对于reentrantlock你还有什么不了解的吗?请继续通过奇Q工具网的常见问题栏目来了解吧,有更多java常见问题及解决方法可以为你分享解答。
推荐阅读:
Synchronized和Reentrantlock区别是什么?简单叙述