java 模擬公告板 wait -notify 實例

關於java多線程中數據同步問題——共享資源,經常用的是生產者和消費這問題,類似的還有公告板的問題。這裏給一個實例。

首先說公告板,只有公告板上有內容,瀏覽者才能讀取內容,如果公告板沒有內容,那麼必須等待先寫入,只有寫入了才能讀取。

所以應該有三個實體類:

一個是MessageBoard即公告板

Reader 讀取

Writer 寫入

對於通俗的約定來說,公告板開始時是空的,所以必須先寫入信息,這裏用一個boolean類型變量表示是否有信息如果沒有信息,那麼等待寫的進程,否則可以讀

class MessageBoard{//信息板類
    private String message;       
    private boolean ready = false;//信號燈,起始狀態先寫後讀
    public synchronized String read(){//同步的讀方法
       while (ready == false){//如果不能讀取
            try{
               System.out.println("等待讀通知");
               wait();//等待,中斷當前線程執行,釋放對象鎖,直到接到喚醒通知
            } catch (InterruptedException e) { }
    }
    ready = false;//設置可以寫標誌
    notify();   //喚醒寫線程寫數據
    return message;
    }
  
   public synchronized void write(String s){
        while (ready == true){//如果不能寫
            try{
                System.out.println("等待寫通知");
                wait();//等待,中斷當前線程執行,直到接到喚醒通知
            }catch (InterruptedException e){ }
        }
        message = s;//寫信息
        ready = true;//設置可以讀標誌
        notify();//喚醒讀線程進行讀取 
   }
}

 

class Reader extends Thread{//讀信息線程類
     private MessageBoard mBoard;
     public Reader(MessageBoard m){//保存信息板對象以供run方法使用
                 mBoard = m;
     }
    
     public void run(){//線程體
         String s = " ";
         boolean reading = true;
         while( reading ){
            s = mBoard.read();//從信息板對象中讀取信息
            System.out.println("Reader 讀取的信息是: " + s);
            try{
             sleep(300);//讀完一條信息後使當前線程睡眠一段時間
            } catch (InterruptedException e) { }
            if( s.equals("logoff") ) //如果讀到的信息爲logoff則結束讀取
               reading = false;
         }
         System.out.println("Finished: 等待 5 秒退出...");
         try{
             sleep( 5000 );//使當前線程睡眠5秒
         }catch (InterruptedException e) { }
      }
}

class Writer extends Thread{//寫信息線程類
     private MessageBoard mBoard;
     private String messages[ ]= {//要寫入信息板對象中的信息
     "今天是Monday","明天到哪去?","明天是Sunday,在家休息"};
   
    public Writer(MessageBoard m){//保存信息板對象以供run方法使用
         mBoard = m;
    }
   
    public void run(){
       for (int i = 0; i < messages.length; i++){
          mBoard.write(messages[ i ]);//向信息板對象中寫入信息
          System.out.println("Writer 寫入的信息是:" + messages[i] );
          try{
             sleep((int)(Math.random() * 100));//寫完一條信息後使當前線程睡眠一段時間
          } catch (InterruptedException e) { }
       }
       mBoard.write("logoff");//寫入結束信息
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章