一號和二號合租一間房,里面共用一個衛生間對象,這是要用到synchronized關鍵字,一號與二號同時使用衛生間時,一個需要wait()等待被喚醒,另外一個使用完之后衛生間對象被釋放,這時候剛剛使用的需要進入wait()狀態,否則會造成死鎖現象,衛生間資源釋放之后,還需要喚醒另一個正在監聽此對象的線程。
首先構造一個房間類Room,內部構造一號和二號的對象,Object一個衛生間類,當作被線程監聽的類,使用synchronized關鍵字:
synchronized (toliet) {}此時toliet對象被共享{}里面可以給一號和二號的使用操作,而同時該語句在run()方法里面,為了使一號和二號對象調用時不出現死鎖。
/* * 一號和二號同租一間房,共同使用一個廁所,先刷牙,在小便,結束 */class Room extends Thread{ static Room p1 = new Room("一號"); static Room p2 = new Room("二號"); PRivate String name;//代號 static Object toliet = new Object(); Room(String name){ this.name = name; } @Override public void run() { // TODO Auto-generated method stub synchronized (toliet) {//只有獲得衛生間的鎖,才可以獲得衛生間里面資源的使用 if(this.name.equals("一號")){ this.brush(); try { toliet.wait(); //刷牙完畢之后在門口等待被喚醒 this.relase();//被喚醒之后開始小便,一號小便完之后要喚醒二號 toliet.notify(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ this.brush(); toliet.notify();//讓一號進來,自己等到被喚醒 try { toliet.wait(); this.relase(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //刷牙的方法 public void brush(){ System.out.println(this.name+"正在刷牙"); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(this.name+"刷牙完畢"); } //解小便 public void relase(){ System.out.println(this.name+"正在小便"); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(this.name+"小便完畢"); }}public class start { public static void main(String[] args) { // TODO Auto-generated method stub Room.p1.start(); Room.p2.start(); }}很簡單的synchronized關鍵字使用,兩個線程共同監聽一個對象,注意邏輯表達不要出現混亂,一個線程被喚醒,另一個立馬進入wait()狀態,上面是完整代碼,同時要注意線程被喚醒,或者進入wait()狀態,是共用對象喚醒正在監聽的的線程和正在使用該對象的線程,比如:
toliet.wait(); //刷牙完畢之后在門口等待被喚醒 this.relase();//被喚醒之后開始小便,一號小便完之后要喚醒二號 toliet.notify();
是<Object>toliet.wait()和toliet.notify(),如果此處用this,或者其他的線程對象代替,則會出現死鎖。
新聞熱點
疑難解答