最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java等待喚醒機(jī)制原理實(shí)例解析

 更新時(shí)間:2020年01月20日 15:01:52   作者:LeeHua  
這篇文章主要介紹了Java等待喚醒機(jī)制原理實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這篇文章主要介紹了Java等待喚醒機(jī)制原理實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

線(xiàn)程的狀態(tài)

首先了解一下什么是線(xiàn)程的狀態(tài),線(xiàn)程狀態(tài)就是當(dāng)線(xiàn)程被創(chuàng)建(new),并且啟動(dòng)(start)后,它不是一啟動(dòng)就進(jìn)入了執(zhí)行狀態(tài)(run),也不是一直都處于執(zhí)行狀態(tài)。

這里說(shuō)一下Java 的Thread類(lèi)里面有一個(gè)State方法,這個(gè)方法里面涵蓋了6種線(xiàn)程的狀態(tài),如下:

public enum State {
  // 尚未啟動(dòng)的線(xiàn)程的線(xiàn)程狀態(tài)。
  NEW,

  // 可運(yùn)行線(xiàn)程的線(xiàn)程狀態(tài)。
  RUNNABLE,

  // 線(xiàn)程的線(xiàn)程狀態(tài)被阻塞,等待監(jiān)視器鎖定。
  BLOCKED,

  // 等待線(xiàn)程的線(xiàn)程狀態(tài)。
  WAITING,

  // 具有指定等待時(shí)間的等待線(xiàn)程的線(xiàn)程狀態(tài)。
  TIMED_WAITING,

  // 終止線(xiàn)程的線(xiàn)程狀態(tài)。
  TERMINATED;
}

導(dǎo)致這六種線(xiàn)程狀態(tài)發(fā)生的條件

New -- 新建

線(xiàn)程剛被創(chuàng)建,不過(guò)還沒(méi)有被啟動(dòng)(還沒(méi)有調(diào)用start方法)

Runnable -- 可運(yùn)行

處于可運(yùn)行狀態(tài)的線(xiàn)程正在Java虛擬機(jī)中執(zhí)行,但是它可能正在等待來(lái)自操作系統(tǒng)(例如處理器)的其他資源。

Blocked -- 鎖阻塞
當(dāng)一個(gè)線(xiàn)程想獲取一個(gè)對(duì)象鎖,不過(guò)該對(duì)象鎖被其它的線(xiàn)程持有時(shí),該線(xiàn)程就會(huì)進(jìn)入鎖阻塞狀態(tài);當(dāng)該線(xiàn)程持有鎖的時(shí)候,該線(xiàn)程將會(huì)變成可運(yùn)行的狀態(tài)。

Waiting -- 無(wú)限等待

當(dāng)一個(gè)線(xiàn)程在等待另一個(gè)線(xiàn)程執(zhí)行一個(gè)(喚醒)動(dòng)作時(shí),該線(xiàn)程就會(huì)進(jìn)入無(wú)限等待狀態(tài)。進(jìn)入這個(gè)狀態(tài)后是不能自動(dòng)喚醒的,要等待另一個(gè)線(xiàn)程調(diào)用notify()方法,或notifyall()方法才能夠被喚醒。

Timed_Waiting -- 計(jì)時(shí)等待

類(lèi)似于無(wú)限等待狀態(tài),有幾個(gè)方法有超時(shí)參數(shù),如:Thread.sleep、Object.wait方法。調(diào)用這些方法,進(jìn)入計(jì)時(shí)等待狀態(tài)。計(jì)時(shí)等待狀態(tài)將會(huì)一直保持到超時(shí)期滿(mǎn)或者接收到喚醒通知。

terminated -- 被終止

1、因?yàn)閞un方法的正常退出而死亡。

2、因?yàn)闆](méi)有捕獲的異常,終止了run方法而死亡。

等待喚醒案例切入

顧客要去飯店吃飯,自助下單,說(shuō)明要吃什么,數(shù)量是多少。下完單以后,顧客就等待該飯店廚師做飯菜,也就是Waiting狀態(tài)(無(wú)限等待狀態(tài))。

廚師收到下單信息,開(kāi)始做飯菜,做好飯菜,把飯菜遞到顧客桌面上,顧客看到飯菜已經(jīng)來(lái)了(notify方法),就可以開(kāi)吃了(等待喚醒機(jī)制)。

Java代碼實(shí)現(xiàn)(線(xiàn)程之間的通信)

分析

創(chuàng)建一個(gè)顧客線(xiàn)程:下單,告知廚師要什么菜,菜的數(shù)量,調(diào)用wait方法,放棄CPU的執(zhí)行,進(jìn)入到無(wú)限等待狀態(tài)(Waiting)

創(chuàng)建一個(gè)廚師線(xiàn)程:看到下單,花了3秒鐘做飯菜,做好之后,調(diào)用notify方法,喚醒顧客吃飯了。

注意

顧客線(xiàn)程和廚師線(xiàn)程,必須使用同步代碼塊包裹起來(lái),保證等待和喚醒只能有一個(gè)在執(zhí)行。

同步使用的鎖對(duì)象必須保證唯一。

只有鎖對(duì)象才能夠調(diào)用Object.wait方法和Object.notify方法。

代碼

public class Demo01WaitNotify {
  public static void main(String[] args) {
    // 創(chuàng)建鎖對(duì)象(要保證鎖唯一)
    Object object = new Object();

    // 創(chuàng)建一個(gè)顧客線(xiàn)程
    new Thread() {
      @Override
      public void run() {
        // 使用同步代碼塊包裹起來(lái),保證等待和喚醒只能有一個(gè)在執(zhí)行。
        synchronized (object) {
          // 顧客下單
          System.out.println("我要一個(gè)西虹市炒番茄,一個(gè)馬鈴薯炒土豆,兩碗米飯");
          // 調(diào)用wait方法,放棄CPU的執(zhí)行,進(jìn)入到無(wú)限等待狀態(tài)(Waiting)
          try {
            object.wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          // 喚醒之后(飯菜上來(lái)后),吃飯?。?!真香。
          System.out.println("我就是餓死,從這里跳下去,也不會(huì)吃你們一口飯。。。真香!?。。?);
        }
      }
    }.start();

    // 創(chuàng)建一個(gè)廚師線(xiàn)程
    new Thread() {
      @Override
      public void run() {
        // 廚師收到下單請(qǐng)求,花三秒鐘把飯菜做好
        try {
          Thread.sleep(3000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        // 使用同步代碼塊包裹起來(lái),保證等待和喚醒只能有一個(gè)在執(zhí)行。
        synchronized (object) {
          System.out.println("我的飯菜三秒鐘做好了,你食唔食哦?");
          // 做好之后,調(diào)用notify方法,喚醒顧客吃飯了。
          object.notify();
        }
      }
    }.start();
  }
}

控制臺(tái)輸出:

我要一個(gè)西虹市炒番茄,一個(gè)馬鈴薯炒土豆,兩碗米飯
我的飯菜三秒鐘做好了,你食唔食哦?
我就是餓死,從這里跳下去,也不會(huì)吃你們一口飯。。。真香?。。?!

上面的代碼,存在線(xiàn)程間的通信,那什么又是線(xiàn)程間的通信呢?簡(jiǎn)單的說(shuō),就是多個(gè)線(xiàn)程在處理同一個(gè)資源,但是處理的動(dòng)作(線(xiàn)程的任務(wù))卻不同。如上,廚師線(xiàn)程做飯菜,顧客線(xiàn)程吃飯菜。那為什么要進(jìn)行線(xiàn)程間的通信呢?多個(gè)線(xiàn)程并發(fā)執(zhí)行的時(shí)候,在默認(rèn)情況下CPU是隨機(jī)切換線(xiàn)程的,當(dāng)我們需要多個(gè)線(xiàn)程來(lái)共同完成一件任務(wù),并且希望它們有規(guī)律的執(zhí)行的時(shí)候,那么多線(xiàn)程就之間就需要一些協(xié)調(diào)通信,來(lái)達(dá)到多線(xiàn)程共同操作一份數(shù)據(jù)。

對(duì)代碼中通信的理解:

對(duì)又沒(méi)有飯菜進(jìn)行判斷——

1、沒(méi)有飯菜(False)。

2、顧客下單。

3、廚師做飯菜。

4、顧客線(xiàn)程等待。

5、廚師做好飯菜

6、修改飯菜的狀態(tài)(True)

7、有飯菜,廚師線(xiàn)程提醒顧客線(xiàn)程吃飯菜。

8、廚師線(xiàn)程等待

9、吃完飯菜,修改飯菜的狀態(tài)(False)

這就是顧客線(xiàn)程與廚師線(xiàn)程之間的通信。以此類(lèi)推,其它Java程序中多線(xiàn)程的通信也是同樣的道理。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

青州市| 缙云县| 吴旗县| 息烽县| 晋江市| 府谷县| 宝坻区| 旌德县| 临朐县| 广灵县| 德惠市| 合作市| 垣曲县| 南陵县| 定州市| 民县| 普定县| 民和| 黑龙江省| 玉龙| 永年县| 固原市| 湘乡市| 东山县| 合川市| 东辽县| 安平县| 延川县| 平湖市| 东安县| 军事| 海安县| 榆中县| 通州区| 米脂县| 米易县| 武邑县| 梓潼县| 乐亭县| 增城市| 陈巴尔虎旗|