zoukankan      html  css  js  c++  java
  • 锁和AQS

    定义

    package java.util.concurrent.locks;
    import java.util.concurrent.TimeUnit;
    
    public interface Lock {
    
        void lock();
    
        void lockInterruptibly() throws InterruptedException;
    
        boolean tryLock();
    
        boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    
        void unlock();
    
        Condition newCondition();
    }
    
    

    优点

    • 持续等待-lock()
    • 可中断-lockInterruptibly()
    • 非阻塞-tryLock() 没有公平可言!
    • 可超时-tryLock(long time, TimeUnit unit)
    • 非阻塞块使用
    • 任意链式锁:a+、b+、c+、a-、c-、b-

    缺点

    • 有使用要求
     Lock l = ...;
     l.lock();
     try {
       // access the resource protected by this lock
     } finally {
       l.unlock();
     }}
    
    

    特点

    • 定义了锁的基本使用需求方法:独占(如定时任务)或者保持时序(如计时器)

    • 普通接口+普通实现类:意味着任何人都可以实现

    • 纯code实现,没有特殊的JVM底层支持

    • 提供了抽象支持AbstractQueuedSynchronizer

    如何实现

    • 使用一个标志位表示锁是否被获取
    • 使用一个数据结构保存等待的线程

    AbstractQueuedSynchronizer

    • 使用int表示状态,支持重入
    • 使用CLH变种队列实现等待队列:双向链表,pre可靠,状态保存在前继节点中,有虚拟头节点
    • 支持独占和共享模式
    • 使用LockSupport进行线程阻塞

    状态变量

    • 使用int表示状态,更具拓展性

    CLH队列

    • 使用反向单链表实现
    • 公平锁
    • 不断自旋,获取前继节点状态
    • CLH详情链接

    独占模式和共享模式

    • 独占模式只支持一个线程获取锁:ReentrantLock
    • 共享模式支持多个线程同时获取锁:Semaphore

    LockSupport

    • park 阻塞线程
    • unpark 取消阻塞线程

    AQS实现-ReentrantLock

    • 可重入,独占模式

    • 通过Sync继承AbstractQueuedSynchronizer,实现独占获取和释放

    • Sync具体实现分为公平和非公平两种,区别在于获取时是否能插队

    • ReentrantLock实现Lock接口,具体实现调用Sync

    公平锁

    lock细节

    1. 没人排队,尝试获取锁
    2. 自己在排队,重入
    3. 别人在排队,自己进入队列,设置pre状态,park

    unlock细节

    1. 必须是获得锁的线程,不然报错
    2. 释放状态,如果完全释放,解除独占线程
    3. 如果完全释放,唤醒第一个等待线程

    AQS实现-Semaphore

    • 不可重入,共享模式
    • 初始化一个状态值,获取时判断状态值是否超过最大值,超过获取失败,不超过获取成功

    AQS实现-CountDownLatch

    • 初始化一个状态值,每次countDown的时候释放1
    • await等待获取锁,当countDown完成后,await获取锁成功

  • 相关阅读:
    Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法
    Android Studio 汉化包
    Genymotion模拟器下载及安装步骤详解
    react native 搭建开发环境——Mac
    ::before和::after伪元素的用法
    前端面试题整理
    echarts图表自适应
    下拉加载更多
    vue之webpack+vuecli打包生成资源相对引用路径与背景图片的正确引用
    微信小程序之tab切换
  • 原文地址:https://www.cnblogs.com/zby9527/p/13385796.html
Copyright © 2011-2022 走看看