这是K&B学习指南的代码
class Account {
private int balance = 50;
public int getBalance() {
return balance;
}
public void withdraw(int amount) {
balance = balance - amount;
}
}
public class AccountDanger implements Runnable {
private Account acct = new Account();
public static void main (String [] args) {
AccountDanger r = new AccountDanger();
Thread one = new Thread(r);
Thread two = new Thread(r);
one.setName("Fred");
two.setName("Lucy");
one.start();
two.start();
}
public void run() {
for (int x = 0; x < 5; x++) {
makeWithdrawal(10);
if (acct.getBalance() < 0) {
System.out.println("account is overdrawn!");
}
}
}
private synchronized void makeWithdrawal(int amt) {
if (acct.getBalance() >= amt) {
System.out.println(Thread.currentThread().getName()
+ " is going to withdraw");
try {
Thread.sleep(500);
} catch(InterruptedException ex) { }
acct.withdraw(amt);
System.out.println(Thread.currentThread().getName()
+ " completes the withdrawal");
} else {
System.out.println("Not enough in account for "
+ Thread.currentThread().getName()
+ " to withdraw " + acct.getBalance());
}
}
}我得到的结果就像
然而,这本书的结果如下:
任何人都可以帮我解释为什么会有这种区别。谢谢!
发布于 2014-05-30 10:08:49
它可以按任何顺序发生。我想这本书想要展示的是:
如果有多方参与,即。X和Y
X is going to withdraw将严格地称为,后面是X completes the withdrawal,而绝不是Y ...,因为这两条语句都在synchronized方法中,这保证了一个和唯一一个< code >E 211线程可以在给定的时间点执行该代码块。
发布于 2014-05-30 10:10:06
这是因为您的同步块仅用于函数makeWithdrawal。首先,Fred调用makeWithdrawal,并在其他线程上阻止对该函数的调用,一旦函数停止,队列中的每个线程都会调用。这个案子是露西。要让弗雷德在其他人之前完成他的工作,请尝试阻止run方法的所有内容,如下所示
public synchronized void run() {
for (int x = 0; x < 5; x++) {
System.out.println(Thread.currentThread().getName()
+ " Start calling");
makeWithdrawal(10);
if (acct.getBalance() < 0) {
System.out.println("account is overdrawn!");
}
}
}或
public void run() {
synchronized (this) {
for (int x = 0; x < 5; x++) {
System.out.println(Thread.currentThread().getName()+ " Start calling");
makeWithdrawal(10);
if (acct.getBalance() < 0) {
System.out.println("account is overdrawn!");
}
}
}
}发布于 2014-05-30 10:20:11
我已经执行了你提供的代码。结果是:
Fred is going to withdraw
Fred completes the withdrawal
Lucy is going to withdraw
Lucy completes the withdrawal
Fred is going to withdraw
Fred completes the withdrawal
Lucy is going to withdraw
Lucy completes the withdrawal
Lucy is going to withdraw
Lucy completes the withdrawal
Not enough in account for Fred to withdraw 0
Not enough in account for Fred to withdraw 0
Not enough in account for Fred to withdraw 0
Not enough in account for Lucy to withdraw 0
Not enough in account for Lucy to withdraw 0这是完全不同的结果,你上面提到的。当一个线程为一个对象执行同步方法时,调用同一对象同步方法的所有其他线程都会被阻塞,直到完成第一个线程为止。与同步方法退出时一样,它会自动建立发生关系,然后再与对同一对象的同步方法的任何后续调用建立关系。因此,每次输出都是不同的。
https://stackoverflow.com/questions/23951667
复制相似问题