2013-12-11 47 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返回