關於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) { }
}
}
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");//寫入結束信息
}
}