zoukankan      html  css  js  c++  java
  • 源码解析-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()   唤醒所有等待的节点

  • 相关阅读:
    notepad++中使用正则表达式
    python 使用多线程
    EMS查看及修改邮箱发送和接受邮件大小的方法
    EMS修改邮箱容量限制的方法
    EMS查看邮箱容量限制的方法
    EMS批量为用户分配邮箱
    EMS已有用户分配邮箱方法
    EMS创建独立新用户并分配邮箱
    【转载】【zabbix】自定义监控项key值
    Centos6.9 安装zabbix3.4 过程
  • 原文地址:https://www.cnblogs.com/ttaall/p/13969741.html
Copyright © 2011-2022 走看看