Semaphore入門學(xué)習(xí)

semaphore

semaphore(信號量)應(yīng)用在并發(fā)領(lǐng)域編程,使用信號量能夠控制多線程執(zhí)行的并發(fā)執(zhí)行數(shù)。信號量機(jī)制建立在信號量模型之上,所以了解信號量模型才能了解信號量機(jī)制。

信號量模型

信號量模型由一個(gè)計(jì)數(shù)器,一個(gè)等待隊(duì)里,三個(gè)方法組成。信號量模型:


信號量模型圖

等待隊(duì)列:線程阻塞后線程存放的隊(duì)里。
計(jì)數(shù)器: 用于統(tǒng)計(jì)正在運(yùn)行或等待的線程數(shù)值。
三個(gè)方法:

  • Init()計(jì)數(shù)器的初始值
  • up()計(jì)數(shù)器的值加1。如果此時(shí)計(jì)數(shù)器值的<=0,則喚醒等待隊(duì)里的一個(gè)線程,并從等待隊(duì)列中移除
    -down()計(jì)數(shù)器的值減1。如果此時(shí)的計(jì)數(shù)器值<0,則當(dāng)前的線程被阻塞。否則,線程繼續(xù)執(zhí)行。

三個(gè)方法必須保證原子性,并且原子性由信號量模型的實(shí)現(xiàn)的方法保證。比如Java里面信號量模型是由 java.util.concurrent.Semaphore實(shí)現(xiàn)的,Semaphore這三個(gè)方法都是原子操作。

信號量代碼分析

信號量模型實(shí)現(xiàn)代碼例子:

class Semaphore{
  // 計(jì)數(shù)器
  int count;
  // 等待隊(duì)列
  Queue queue;
  // 初始化操作
  Semaphore(int c){
    this.count=c;
  }
  // 
  void down(){
    this.count--;
    if(this.count<0){
      // 將當(dāng)前線程插入等待隊(duì)列
      // 阻塞當(dāng)前線程
    }
  }
  void up(){
    this.count++;
    if(this.count<=0) {
      // 移除等待隊(duì)列中的某個(gè)線程 T
      // 喚醒線程 T
    }
  }
}

-----------------------------------業(yè)務(wù)邏輯代碼----------------------------------------
static int count

// 初始化信號量
static final Semaphore s 
    = new Semaphore(1);
// 用信號量保證互斥    
static void addOne() {
  s.down();
  try {
    count+=1;
  } finally {
    s.up();
  }
}


假設(shè)此時(shí)有兩個(gè)線程T1和T2同時(shí)訪問addOne()方法。由于down()方法是原子性的,所以只能有1個(gè)線程(T1)把計(jì)數(shù)器的值減到0,另一個(gè)線程(T2)把計(jì)數(shù)器減到-1。對于T1,計(jì)數(shù)器的值是0,大于等于0,所以繼續(xù)執(zhí)行。對于T2,計(jì)數(shù)器的值是-1,小于等于0,所以會把T2加入到阻塞隊(duì)列,然后當(dāng)前線程阻塞。T1執(zhí)行完畢之后,計(jì)數(shù)器加1,此時(shí)計(jì)數(shù)器的值是0,小于等于0,此時(shí)會移除等待隊(duì)列中的T2,然后在喚醒T2。

java信號量模型實(shí)現(xiàn)

java信號量模型由java.util.concurrent.Semaphore實(shí)現(xiàn)


Semaphore類方法
  • acquire()方法實(shí)現(xiàn)信號量模型的down()方法。
  • relase()方法實(shí)現(xiàn)信號量模型的up()方法。

java通過提供acquire(int permits)方法減去指定數(shù)值的計(jì)數(shù)器值,以及通過提供tryAcquire(int permits, long timeout, TimeUnit unit)指定獲取信號量的超時(shí)時(shí)間。通過NonfairSync和FairSync類提供非公平和公平兩種獲取信號量實(shí)現(xiàn)機(jī)制。FairSync通過遍歷查看當(dāng)前線程是否在隊(duì)列頭節(jié)點(diǎn)來決定是否有資格去獲取信號量,NonfairSync通過CAS機(jī)制來搶占式來獲取信號量。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java SE 基礎(chǔ): 封裝、繼承、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體,并盡...
    Jayden_Cao閱讀 2,247評論 0 8
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,663評論 1 32
  • 線程 操作系統(tǒng)線程理論 線程概念的引入背景 進(jìn)程 之前我們已經(jīng)了解了操作系統(tǒng)中進(jìn)程的概念,程序并不能單獨(dú)運(yùn)行,只有...
    go以恒閱讀 1,796評論 0 6
  • 一. 操作系統(tǒng)概念 操作系統(tǒng)位于底層硬件與應(yīng)用軟件之間的一層.工作方式: 向下管理硬件,向上提供接口.操作系統(tǒng)進(jìn)行...
    月亮是我踢彎得閱讀 6,162評論 3 28
  • 在上個(gè)世紀(jì)安靜的中國南方山水小鎮(zhèn)里,一個(gè)外國女人,看著自己的丈夫安詳?shù)奶稍谥袊南樨惡舆叄S他一同埋藏的是自己不堪...
    街上的野子閱讀 543評論 0 0

友情鏈接更多精彩內(nèi)容