• 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, 尝试获得写锁会导致死锁, 必须先释放读锁, 即不支持锁升级

  • 相关阅读:
    各种类型的Dialog
    短信验证码的使用
    监听开机广播
    实现点击两次返回键退出
    Android 遮罩层效果--制作圆形头像
    Native方法的使用
    如何给数字添加分隔符
    自定义Toast
    Android px、dp、sp之间相互转换
    android:scrollbarStyle属性及滚动条和分割线覆盖问题
  • 原文地址:https://www.cnblogs.com/bianzy/p/6576404.html
Copyright © 2020-2023  润新知