• 源码解析-Semaphore


    创建 Semaphore 实例的时候,需要一个参数 permits,

    这个基本上可以确定是设置给 AQS 的 state 的,

    然后每个线程调用 acquire 的时候,执行 state = state - 1,

    release 的时候执行 state = state + 1,

    当然,acquire 的时候,如果 state = 0,说明没有资源了,需要等待其他线程 release。

    基本操作

    1.创建Semaphore对象,初始化permits

    2. semaphore.acquire()  占用一个位置

    3. semaphore.release() 取消一个位置   

    Semaphore原理是AQS 可以理解成 就是多个对象共持有的一把锁,达到permits数量 再想争抢锁就要等待,持有锁的对象释放。也区分公平锁非公平锁竞争原则

    源码解析:

    1. new Semaphore()

      

     没啥好说的   初始化设置AQS的state

    2. acquire(int permits)  占用几个空位的资源

    acquireSharedInterruptibly()  老中断处理了

     

    if (tryAcquireShared(arg) < 0) //说明占位失败  要么是没那么多位置给你占  要么是CAS失败了

    3. tryAcquireShared()   非公平锁的实现

     

     死循环(){

    获取当前的state值;

    remaining = state - 想要占位数;

    if(如果想要占位数>state总数  或者CAS成功 ){

      返回剩余位数;

    }

    }

    4.  doAcquireSharedInterruptibly()  占位失败,加入到阻塞队列

     将节点封装成Node 加入到阻塞队列

    for( 死循环){

      判断前直接点是不是头节点;

      如果前置节点是头节点,尝试去抢占位置,

      抢占成功了,大吉大利 队列中删除节点,结束;

      抢失败了 挂起等待唤醒。

    }

    finally{

      如果中途被中断了 就退出争抢 不玩了;

    }

    5. relase()  释放资源

     

    6. tryReleaseShared()  尝试释放共享资源   改state值

     for(死循环){

      获取当前state值;

      next = state + 要释放的位置数;

      CAS交换

    }

    7. doReleaseShared()   唤醒所有等待的节点

  • 相关阅读:
    mongodb的安装与启动(centos7)
    使用tengine解决负载均衡的session问题
    nginx 负载均衡 使用ip_hash方式解决session问题 测试
    查看linux服务器状态常用命令
    swagger
    使用gtest(googletest)进行c++单元测试
    程序员的字符艺术
    使用gdb调试c++程序
    使用c++开发跨平台的程序
    Orleans之EventSourcing
  • 原文地址:https://www.cnblogs.com/ttaall/p/13969741.html
Copyright © 2020-2023  润新知