2013-12-11 89 views
-1

夥計, 我正在學習有關Java多線程的內容。我的代碼如下:Java多線程通信不起作用

類:ATM

package com.frank.threadlearning; 

public class ATM { 
private String atmNo; 
private boolean isAvailable = true; 

public ATM(){ 
    this("ATM-00"); 
} 

public ATM(String s){ 
    this.atmNo = s; 
} 

public String getATMNo(){ 
    return this.atmNo; 
} 

public synchronized void useATM(){ 
    try{ 
     if(!isAvailable){ 
      System.out.println(this.atmNo + " is unavailable. Please wait..."); 
      this.wait(); 
     } 
     isAvailable = false; 
     System.out.println(Thread.currentThread().getName() + " is using " + this.atmNo); 
     Thread.sleep(5000); 
     System.out.println(this.atmNo + " is available."); 
     isAvailable = true; 
     this.notifyAll(); 

    }catch(InterruptedException ie){ 
     ie.printStackTrace(); 
    } 
} 

public String getStatus(){ 
    return this.atmNo + " is available? " + this.isAvailable; 
} 


} 

類:ATMUser

package com.frank.threadlearning; 

public class ATMUser implements Runnable{ 
private ATM atm; 
private String name; 

public ATMUser(ATM atm, String s){ 
    this.atm = atm; 
    this.name = s; 
} 

public String getName(){ 
    return this.name; 
} 

public void run(){ 
    System.out.println(this.name + " tries to use the " + this.atm.getATMNo()); 
    this.atm.useATM(); 
} 

} 

類:ATMRoom

package com.frank.threadlearning; 

public class ATMRoom { 

public static void main(String[] args){ 
    //Define two ATM objects. 
    ATM atm1 = new ATM("ATM-01"); 
    ATM atm2 = new ATM("ATM-02"); 
    //Define six ATMUser objects. 
    ATMUser user11 = new ATMUser(atm1,"Frank"); 
    ATMUser user12 = new ATMUser(atm1,"Kate"); 
    ATMUser user13 = new ATMUser(atm1,"Mary"); 
    ATMUser user21 = new ATMUser(atm2,"John"); 
    ATMUser user22 = new ATMUser(atm2,"Soy"); 
    ATMUser user23 = new ATMUser(atm2,"Claire"); 

    Thread thread11 = new Thread(user11,user11.getName()+"Thread"); 
    Thread thread12 = new Thread(user12,user12.getName()+"Thread"); 
    Thread thread13 = new Thread(user13,user13.getName()+"Thread"); 
    Thread thread21 = new Thread(user21,user21.getName()+"Thread"); 
    Thread thread22 = new Thread(user22,user22.getName()+"Thread"); 
    Thread thread23 = new Thread(user23,user23.getName()+"Thread"); 

    thread11.start(); 
    thread12.start(); 
    thread13.start(); 
    thread21.start(); 
    thread22.start(); 
    thread23.start(); 




} 


} 

我期待的結果是這樣的:

凱特試圖使用ATM-01

KateThread使用ATM-01

弗蘭克試圖使用ATM-01

ATM-01不可用。請稍候...

Mary試圖使用ATM-01

ATM-01不可用。請稍候...

大豆嘗試使用ATM-02

SoyThread使用ATM-02

約翰試圖使用ATM-02

ATM-02不可用。請稍候...

克萊爾試圖使用ATM-02

ATM-02不可用。請稍候...

ATM-01可用。

MaryThread正在使用ATM-01

ATM-02可用。

ClaireThread使用ATM-02

ATM-01是可用的。

FrankThread正在使用ATM-01

ATM-02可用。

JohnThread使用ATM-02

ATM-01是可用的。

ATM-02可用。

但是,實際上,下面的輸出從未出現過。

XXX不可用。請稍候...

那麼有人能告訴我並向我解釋嗎? 謝謝。

+0

1)爲了更好地幫助越早,後期。 [SSCCE](http://sscce.org/)。 2)源代碼中的單個空白行是* always *就足夠了。 '{'之後或'}'之前的空行通常也是多餘的。 –

回答

0

因爲useATM方法是同步的,所以一次只有一個線程可以輸入給定ATM的useATM方法。

0

我覺得你想要做的就是睡在監視器外面。在代碼方面:使用一個同步塊(synchronized(this){...}作爲第一個使用的ATM位,然後是try和try內的sleep,最後是第二個使用atM的最後部分的同步塊,這會得到你正在尋找的效果對於

最後一件事,但:。取而代之的if(! isAvailable)使用while(! isAvailable)的原因是沒有保證的等待線程會發現isAvailable真正在從wait返回