关于jav:话说-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示意偏心

有问题能够留言哦,也能够公众号留言(回复快):

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理