java 線程之間通訊以及notify與notifyAll區別。

來源:互聯網
上載者:User

jvm多個線程間的通訊是通過 線程的鎖、條件陳述式、以及wait()、notify()/notifyAll組成。

下面來實現一個啟用多個線程來迴圈的輸出兩個不同的語句。

package com.app.thread;

import javax.swing.plaf.SliderUI;
/**
 * 看出問題來
 * @author Gordon
 *
 */
public class LockDemo {
 public static void main(String[] args) {
//  System.out.println("lock");

  final OutTurn ot = new OutTurn();
  
  for(int j=0;j<100;j++){

   new Thread(new Runnable() {

    public void run() {
//     try {
//      Thread.sleep(10);
//     } catch (InterruptedException e) {
//      e.printStackTrace();
//     }
     for (int i = 0; i <5; i++) {     
      ot.sub();
     }
    }
   }).start();

   new Thread(new Runnable() {

    public void run() {
//     try {
//      Thread.sleep(10);
//     } catch (InterruptedException e) {
//      e.printStackTrace();
//     }
     for (int i = 0; i < 5; i++) {     
      ot.main();
     }
    }
   }).start();
  }

 }
}

class OutTurn {
 private boolean isSub = true;
 private int count=0;

 public synchronized void sub() {
  try {
   while (!isSub) {
    this.wait();
   }
   System.out.println("sub ---- "+count);
   isSub=false;
   this.notify();
  } catch (Exception e) {
   e.printStackTrace();
  }
  count++;

 }

 public synchronized void main() {
  try {
   while(isSub){
    this.wait();
   }
   System.out.println("main (((((((((((( "+count);
   isSub=true;
   this.notify();
  } catch (Exception e) {
   e.printStackTrace();
  }
  count++;
 }
}

不知能否看出問題,第一次寫的時候出現了問題,找了很久才找了出來,一直以來是沒有注意notify與notifyAll()的使用,在此釀成大錯,哎。。。

說明一下notify與notifyAll的區別:

  以上sub和main方法都是用了鎖,所以說多個調用sub方法的線程和多個調用main方法的都會處於阻塞狀態,都會等待一個正在啟動並執行其他線程來喚醒他們,以上代碼使用了notify進行喚醒,notify只能喚醒一個線程,其他等待的線程仍然處於wait狀態,如果調用sub方法的線程執行完後,所有的線程都處於等待狀態,isSub=false了,這時喚醒的是一個sub方法調度線程,那麼while迴圈等於true,則該線程也會處於等待狀態,之後所有的線程處於等待狀態,沒有啟動並執行線程來喚醒他們,這時就產生了死結。如果使用notifyAll()來喚醒所有正在等待該鎖的線程,那麼所有的線程都會處於運行前的準備狀態,就是sub方法執行完後,喚醒了所有等待該鎖的狀態,那麼即使再次喚醒一個sub方法調度線程,那麼該線程再次處於等待狀態後,還有其他的線程可以獲得該鎖,進入運行狀態。所以notify方法很容易引起死結,除非你根據自己的程式設計,確定不會引起死結,notifyAll則是線程的安全喚醒方法。

 

言歸正傳,以上代碼 只需要將sub和main方法中的參數改成this.notifyAll()即可。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.