我是Java线程编程的新手。为了理解线程,我试图编写一个简单的程序来模拟银行帐户。我刚刚实施了提款并尝试对其进行测试。
输出的前几行如下。
T2提款前余额:1000
T2提款后余额:990
T1提款前余额:1000
T1提款后的余额:980
T2提取前的余额:980
T2提取后的余额:970
T1提款前的余额:970
T1提款后的余额:960
我的问题是,为什么输出中的第3行(T1撤回之前的余额:1000)给出的是1000而不是990。如果正确,它应该在第2行。我错过了什么吗?我的方法正确吗?
我的猜测是,试图写写入控制台的两个线程和线程T1都根本没有机会在第二行写它。
class BankAccount {
private volatile int balance;
public BankAccount(int b){
balance = b;
}
public BankAccount(){
balance = 0;
}
synchronized public int getBalance(){
return balance;
}
synchronized public int withdraw(int w)
{
int b = getBalance();
if(w <= b){
balance = balance-w;
return w;
}
else
return 0;
}
}
class WithdrawAccount implements Runnable{
private BankAccount acc;
private int amount;
public WithdrawAccount(){
acc = null;
amount = 0;
}
public WithdrawAccount(BankAccount acc,int amount){
this.acc = acc;
this.amount = amount;
}
public void run() {
int w;
for(int i =0; i<20; i++){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Balance before "+Thread.currentThread().getName()+" withdrawl: "+acc.getBalance());
w = acc.withdraw(amount);
System.out.println("Balance after "+Thread.currentThread().getName()+" withdrawl: "+acc.getBalance());
//System.out.println("amount with drawn by: "+Thread.currentThread().getName()+" "+w);
}
}
}
public class TestBankAccount{
public static void main(String[] args) {
BankAccount b = new BankAccount(1000);
WithdrawAccount w = new WithdrawAccount(b,10);
Thread wt1 = new Thread(w);
wt1.setName("T1");
Thread wt2 = new Thread(w);
wt2.setName("T2");
wt1.start();
wt2.start();
}
}
最佳答案
您没有做任何事情来同步您的run方法,因此撤回前后的printlns和撤回本身不是原子的。您正在进行线程交织。