多線程之間的通信

多線程之間的通信

  • 線程通信概念:線程是操作系統(tǒng)中獨(dú)立的個(gè)體,但這些個(gè)體如果不經(jīng)過特殊處理就不能成為一個(gè)整體夹抗,線程間的通信就成為整體的必用方式之一膘格。當(dāng)線程存在通信指揮谷婆,系統(tǒng)間的交互性會(huì)更強(qiáng)大,在提高CPU利用率的同時(shí)還會(huì)使開發(fā)人員對(duì)線程任務(wù)在處理過程中進(jìn)行有效的把控與監(jiān)督径玖。
  • 使用wait/notify 方法實(shí)現(xiàn)線程間的通信痴脾。(注意這兩個(gè)方法都是Object類的方法,換句話說Java為所有的對(duì)象都提供了這兩個(gè)方法)
    • wait 和 notify 必須配合synchronized 關(guān)鍵字使用梳星。
    • wait 方法釋放鎖赞赖,notify 方法不釋放鎖

使用輪詢的方式通信

public static void main(String[] args) {
  final ListAddTest1 list = new ListAddTest1();
  Thread thread_1 = new Thread(new Runnable() {
    @Override
    public void run() {
      for (int i = 0; i < 10; i++) {
        try {
          list.add();
          System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + " 添加一個(gè)元素滚朵!");
          Thread.sleep(500);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }, "Thread-1");

  Thread thread_2 = new Thread(new Runnable() {
    @Override
    public void run() {
      while (true) {
        if (list.size() == 5) {
          System.out.println("當(dāng)前線程收到通知:" + Thread.currentThread().getName() + " list size = 5 線程停止..");
          throw new RuntimeException();
        }
      }
    }
  }, "Thread-2");

  thread_1.start();
  thread_2.start();
}

使用notify 和 wait 方法通信

  • 如上述的代碼,thread-2 線程一種處于一種輪詢的方式前域,我們可以修改Java中多線程通信的方式來改造辕近, 使用notify 和 wait.
    • 注意必須配合 synchronized 關(guān)鍵字來使用,否則會(huì)報(bào) java.lang.IllegalMonitorStateException 非法監(jiān)控異常
    • 必須先啟動(dòng) wait 方法的線程话侄,因?yàn)閚otify 方法不會(huì)釋放鎖亏推,先啟動(dòng)notify 方法的線程,執(zhí)行到 notify 方法的時(shí)候年堆,并沒有線程在 wait.
public static void main(String[] args) {
  final ListAddUseNotifyAndWait list = new ListAddUseNotifyAndWait();
  final Object lock = new Object();
  Thread thread_1 = new Thread(new Runnable() {
    @Override
    public void run() {
      //                synchronized (lock) {
      try {
        for (int i = 0; i < 10; i++) {
          list.add();
          System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + " 添加一個(gè)元素吞杭!");
          Thread.sleep(500);
          if (list.size() == 5) {
            System.out.println("已經(jīng)發(fā)出通知!");
            lock.notify();// notify 方法不會(huì)釋放鎖
          }
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      //                }
    }
  }, "Thread-1");

  Thread thread_2 = new Thread(new Runnable() {
    @Override
    public void run() {
      try {
        //                    synchronized (lock) {
        if (list.size() != 5) {
          System.out.println("Thread-2進(jìn)入...");
          lock.wait();// wait 方法會(huì)釋放鎖
        }
        System.out.println("當(dāng)前線程收到通知:" + Thread.currentThread().getName() + " list size = 5 線程停止..");
        throw new RuntimeException();
        //                    }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }, "Thread-2");

  // 需要先啟動(dòng) thread_2 , 因?yàn)槿绻葐?dòng) thread_1变丧, 那么 notify 方法不會(huì)釋放鎖芽狗,
  // t1線程完全執(zhí)行完才會(huì)釋放鎖, 當(dāng)t1到notify 方法的時(shí)候,并沒有 其他線程在 wait
  thread_2.start();
  thread_1.start();
}

使用CountDownLatch 閉鎖來進(jìn)行通信

  • 在使用notify 和 wait 來進(jìn)行通信的時(shí)候還有一個(gè)問題痒蓬,在程序中我們必須等 thread-1 執(zhí)行完成童擎,才會(huì)釋放鎖來通知 thread-2,這會(huì)造成不實(shí)時(shí)的問題攻晒。如果需要程序在 list.size 為5 的時(shí)候顾复,就立馬執(zhí)行 thread-2 中的線程的話,我們就可以使用 CountDownLatch 的方式來進(jìn)行通信
final CountDownLatch countDownLatch = new CountDownLatch(1);
Thread thread_1 = new Thread(new Runnable() {
  @Override
  public void run() {
    try {
      for (int i = 0; i < 10; i++) {
        list.add();
        System.out.println("當(dāng)前線程:" + Thread.currentThread().getName() + " 添加一個(gè)元素鲁捏!");
        Thread.sleep(500);
        if (list.size() == 5) {
          System.out.println("已經(jīng)發(fā)出通知芯砸!");
          countDownLatch.countDown();
        }
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}, "Thread-1");

Thread thread_2 = new Thread(new Runnable() {
  @Override
  public void run() {
    try {
      if (list.size() != 5) {
        System.out.println("Thread-2進(jìn)入...");
        countDownLatch.await();
      }
      System.out.println("當(dāng)前線程收到通知:" + Thread.currentThread().getName() + " list size = 5 線程停止..");
      throw new RuntimeException();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}, "Thread-2");

thread_1.start();
thread_2.start();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市给梅,隨后出現(xiàn)的幾起案子假丧,更是在濱河造成了極大的恐慌,老刑警劉巖动羽,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件包帚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡运吓,警方通過查閱死者的電腦和手機(jī)渴邦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羽德,“玉大人几莽,你說我怎么就攤上這事≌玻” “怎么了章蚣?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我纤垂,道長(zhǎng)矾策,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任峭沦,我火速辦了婚禮贾虽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吼鱼。我一直安慰自己蓬豁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布菇肃。 她就那樣靜靜地躺著地粪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪琐谤。 梳的紋絲不亂的頭發(fā)上蟆技,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音斗忌,去河邊找鬼质礼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛织阳,可吹牛的內(nèi)容都是我干的眶蕉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼唧躲,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼妻坝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惊窖,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厘贼,沒想到半個(gè)月后界酒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嘴秸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年毁欣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岳掐。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凭疮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出串述,到底是詐尸還是另有隱情执解,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布纲酗,位于F島的核電站衰腌,受9級(jí)特大地震影響新蟆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜右蕊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一琼稻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧饶囚,春花似錦帕翻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至闹丐,卻和暖如春横殴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卿拴。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工衫仑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人堕花。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓文狱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親缘挽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞄崇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容