ReentrantLock

ReentrantLock

一、 使用

1.1 简单使用

public class LockTest {// 新建锁Lock lock  =  new ReentrantLock();public static void main(String[] args) {// 测试LockTest test = new LockTest();test.te();}public void te(){try {// 获取锁lock.lock();System.out.println("获取到锁执行代码!");} catch (Exception e) {e.printStackTrace();} finally {// 一定注意 在finally中释放锁lock.unlock();}}}

1.2 tryLock

Lock比synchronized还是多一些功能的,比如可以设置规定时间内获取不到锁就返回,不一直阻塞。

一个不合时宜的例子就是:

synchronize就是一个舔狗,一直舔 直到天荒地老

lock 的 tryLock 就像是一个渣男,轻轻尝试一下,不合适抓紧下一个

public class LockTest02 {// 新建锁Lock lock  =  new ReentrantLock();public static void main(String[] args) {// 测试LockTest02 test = new LockTest02();new  Thread(()->test.te()).start();// test::teTryLock lambda写法new  Thread(test::teTryLock).start();}private void teTryLock() {boolean res = false;try {// 尝试获取 5秒钟获取不到就结束 res = lock.tryLock(5,TimeUnit.SECONDS);if (res) {System.out.println("teTryLock获取到锁了,执行获取到锁的代码");} else{System.out.println("teTryLock没有获取到锁 执行没有获取到锁的代码");}} catch (Exception e) {e.printStackTrace();} finally {// 如果获取到锁了 再释放if (res) {lock.unlock();}}}public void te(){try {// 获取锁lock.lock();System.out.println("te获取到锁执行代码!");Thread.sleep(10000);} catch (Exception e) {e.printStackTrace();} finally {// 一定注意 在finally中释放锁lock.unlock();System.out.println("te释放锁!");}}}输出结果:
te获取到锁执行代码!
teTryLock没有获取到锁 执行没有获取到锁的代码 
te释放锁!

1.3 lockInterruptibly

synchronized 如果开始等待是不能结束的

但是Lock使用lockInterruptibly 可以被中断 在异常捕获里捕获异常 然后做一些后置处理

public class LockTest03 {// 新建锁Lock lock  =  new ReentrantLock();public static void main(String[] args) throws InterruptedException {// 测试LockTest03 test = new LockTest03();new  Thread(test::te).start();Thread thread = new Thread(test::teLockInterruptibly);thread.start();Thread.sleep(3000);thread.interrupt();}private    void teLockInterruptibly() {boolean res = true;try {// 尝试获取 5秒钟获取不到就结束lock.lockInterruptibly();System.out.println("获取到锁··");} catch (InterruptedException e) {//没有正常获取锁 被Interrupt了res = false;System.out.println("InterruptedException:被打断了 做一些其他处理");} finally {// 如果没被打断 是正常获取锁的(理论上是,也可能有其他异常)   if(res) {   lock.unlock();   }}}public void te(){try {// 获取锁lock.lock();System.out.println("te获取到锁执行代码!");// te 方法睡死过去了Thread.sleep(10000000);} catch (Exception e) {e.printStackTrace();} finally {// 一定注意 在finally中释放锁lock.unlock();System.out.println("te释放锁!");}}}

1.4 公平锁

synchronized是非公平锁 后来的也可能会先获取到锁

Lock锁默认也是非公平锁

非公平锁是什么样的?

用不要脸的小强来做比喻,假设有10个人在排队买饼,小强这时候也来买饼了,不要脸的他直接跑第一个位置,这时候如果正有人在选饼,那他就灰溜溜的走了,如果上一个人刚好买完,下一个人还没有开始选,那不要脸的小强就会趁着这个间隙直接跟老板选饼. 这样对于后边排队的是不公平的 所以称为不公平锁

在ReentrantLock的实现中,不要脸的小强会尝试好几次,最后都失败的话他才会去队尾排队

Lock可以实现公平锁:公平锁就是lock的时候会先去排队队列里边看看,有没有人在排队,有的话站后边去,可以看我写过的AQS ,用公平锁做的举例 讲到了源码层

注意:公平锁不是完全公平,公平锁只是会检查队列里有没有人排队,如果没有自己去申请锁,如果有自己去排队,去检查有没有人排队的时候可能会出现不公平(地铁一个人一大步窜你前边了),进队列的时候也可能会出现不公平(地铁一个人一大步窜你前边了)

 Lock lock  =  new ReentrantLock(true); // true表示公平


上一篇:类实例化


下一篇:递归下降分析程序(语法分析)