zoukankan      html  css  js  c++  java
  • ReentrantLock原理

    ReentrantLock基于AQS(Q:队列 S:同步): CAS修改state, 如果修改state成功, 则表示获得了该锁, 线程继续执行, 否则表示该锁已经被其他线程获得, 本线程被插入队列并挂起.

    1.线程尝试修改state, 成功则继续执行, 否则进入2

    2.把本线程封装成一个node插入队尾, 进行自旋:如果当前node处于队首, 那么再次tryAcquire获取锁, 如果成功, 线程避免被挂起并继续执行, 否则进入3

    3.判断前一个node是否已经取消获得锁, 是则删除前一个node, 否则将线程挂起,进入等待唤醒->4

    4.线程被唤醒, 先检查自身interrupt状态, 如果被被中断则抛出InterruptedException并退出队列, 否则tryAcquire竞争锁

    关于公平锁和非公平锁

    new ReentrantLock(true);

    非公平锁在4时, 调用tryAcquire获得锁, 这时如果有其他线程调用tryAcquire是竞争的. 并不能保证哪个线程获得锁

    而公平锁则是在1时,先判断队列是否为空,如果不为空, 则不会直接调用tryAcquire,而是进入队列, 这样就不会有线程竞争问题

    但是公平锁性能不如非公平锁, 非公平锁在有新线程竞争锁时, 优先是给新线程的, 这样就避免了新线程的挂起

    关于读写锁

    核心是三个状态: 读锁数 / 独占锁线程 / 锁重入数

     1. 获得写锁:

      1> 读锁数量为0

      2> 独占线程是本线程则重入数+acquires或者没有独占线程则设置独占线程为本线程

    2.获得读锁

      1> 如果独占线程为本线程或者独占线程为null则读锁数+1

    锁降级:

      如果已经获得写锁, 那么由于独占线程是本线程可以直接获得读锁, 可直接获得读锁, 此时线程有 读/写 两个锁, 需要释放写锁完成降级

      如果已经获得读锁, 那么由于读锁数量不为0, 尝试获得写锁会导致死锁, 必须先释放读锁, 即不支持锁升级

  • 相关阅读:
    金山快盘的登录提醒
    排列到随机, 到随机选择,对于植物模拟世界 混沌
    转载 多层影藏 和显示
    庆生写的东西
    布料修改器的用法。
    像素相关
    模拟c++ 控件
    侧his
    输出文件
    win7 xp 删除一些 顽固的自动项目
  • 原文地址:https://www.cnblogs.com/bianzy/p/6576404.html
Copyright © 2011-2022 走看看