球员, 我正在学习有关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
Frank尝试使用ATM-01
ATM-01不可用。请等一下......
Mary尝试使用ATM-01
ATM-01不可用。请等一下......
大豆尝试使用ATM-02
SoyThread正在使用ATM-02
John试图使用ATM-02
ATM-02不可用。请等一下......
Claire试图使用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 :(得分:0)
因为useATM方法是同步的,所以一次只有一个线程可以进入给定ATM的useATM方法。
答案 1 :(得分:0)
我认为你想做的就是睡在监视器外面。在代码方面:使用一个synchronized块(synchronized(this){...}
用于第一个useATM。然后是try和try内部的try。最后是useATM的最后一部分的第二个同步块。这将得到你正在寻找的效果。
最后一件事是:而不是if( ! isAvailable )
使用while( ! isAvailable )
。原因是,从isAvailable
返回后,无法保证等待线程会发现wait
为真。