zoukankan      html  css  js  c++  java
  • Lock和Condition

    1 什么是可重入锁

    可重入锁是说一个线程在已经获取了该锁的情况下,还可以再次获取该锁。

    主要的应用场景:

    可重入锁指的是在一个线程中可以多次获取同一把锁,比如:
    一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,

    则该线程可以直接执行调用的方法,而无需重新获得锁;

    ReentrantLock和Synchronized都是可重入锁。

    2 ReentrantLock公平锁和非公平锁

    公平锁按照对锁FIFO的获取顺序来获取锁,在获取锁前会进行一个判断,判断锁的等待队列中是否已经有人,如果有人的话直接获取不成功,也就是说让给别人。

    非公平锁就是抢。

    非公平锁不需要线程的切换,具有更大的系统吞吐,因此jdk默认是非公平锁。

    3 有了锁为什么要引入Condition

     为了实现生产者消费者模式。

    4 AbstractQueuedSynchronizer的condition queue和sync queue 

    为什么要将一个节点从condition queue移动到sync queue?

    5 AbstractQueuedSynchronizer最终是调用LockSupport.park()阻塞和LockSupport.unpark释放线程

    6 ReentrantLock最终也是调用LockSupport.park()阻塞的

    当线程没有获取到ReentrantLock的时候,就会被LockSupport.park()阻塞。

    当获取了该锁的线程释放该锁的时候,会调用LockSupport.unpark()来唤醒sync queue中的一个线程。

    7 Lock和Condition统一于LockSupport.park()和LockSupport.unpark(),准备了两个队列,condition queue和sync queue

    8 Condition为什么要和Lock绑定

    在等待condition之前,必须要先获取其所关联的Lock,这是为什么? 

    就队列而言,是Lock在保护着的,如果不保护好的话,别的线程会抢走,比如放入一个元素,这个时候就乱了。因此,必须要先获取其所关联的lock。

    如果发现队列中没有元素,这个时候该线程就需要等待了。为了不阻塞别的线程前来访问队列,就需要释放其所关联的Lock。

    9 ArrayBlockingQueue的take函数

    获取的该ArrayBlockingQueue的全局的lock还没有释放的时候,如果是该queue是空的,这个时候会阻塞该线程,但是,它的全局lock并没有释放。这样不会带来问题吗? 

    不会带来问题,在await的时候,会自动将全局的lock释放。

    Condition在调用await的时候,会调用fullyRelease,再调用release将sync queue中的head的下一个线程unpark,就是把全局的lock释放。

    这个里面还有一些东西需要进一步搞清楚。 

    10 参考资料

    10.1 彻底理解ReentrantLock

    https://blog.csdn.net/u011521203/article/details/80186741

    转载于:https://www.cnblogs.com/hustdc/p/10919791.html

  • 相关阅读:
    数组
    做了个进制转换图
    类的练习
    3.10l练习
    c#学习第二课
    c#第四课习题
    c#学习第三课
    学习PHP&MYSQL之——字符编码篇(一)
    中缀表达式转换成后缀表达式
    模板方法模式(Template Pattern)
  • 原文地址:https://www.cnblogs.com/twodog/p/12134857.html
Copyright © 2011-2022 走看看