日期:2014-05-20  浏览次数:20740 次

多线程,为什么会出现偶然并且错误的结果
Java code

/**
 * 
 */
package thread;

/**
 * @description 线程同步
 *
 */
public class SynchronizedTest {
    public static void main(String[] args) {
        Account account = new Account("10011",0);
        new DepositThread2("存钱线程",account,300).start();
        new DrawThread2("取钱线程",account,300).start();
    }
}
/**
 * @description 账户-存/取
 *
 */
class Account2{
    private String accountNo;
    private double balance;//余额
    private boolean flag = false;//true代表可取 ,false代表可存
    public Account2(String accountNo,double balance) {
        this.accountNo = accountNo;
        this.balance = balance;
    }
    /**
     * @return the accountNo
     */
    public String getAccountNo() {
        return accountNo;
    }
    /**
     * @param accountNo the accountNo to set
     */
    public void setAccountNo(String accountNo) {
        this.accountNo = accountNo;
    }
    /**
     * @return the balance
     */
    public double getBalance() {
        return balance;
    }
    /**
     * @description 取钱
     * @param drawAmount
     */
    public synchronized void draw(double drawAmount){
        try{
            if(flag){//flag=true , 表示账户还有钱,等待将钱取走
                System.out.println(Thread.currentThread().getName()+" 取钱:"+drawAmount);
                balance -= drawAmount;
                System.out.println("账户余额:"+balance);
                flag = false;//可以存钱
                notifyAll();
            }else{
                wait();
            }
        }catch(Exception e){
        }
    }
    
    /**
     * @description 存钱
     * @param drawAmount
     */
    public synchronized void deposit(double depositAmount){
        try{
            if(flag){//flag=true , 表示账户还有钱,等待将钱取走
                wait();
            }else{
                System.out.println(Thread.currentThread().getName()+" 存钱:"+depositAmount);
                balance += depositAmount;
                System.out.println("账户余额:"+balance);
                flag = true;//可以取钱
                notifyAll();
            }
        } catch (InterruptedException e) {
        }
    }
}
/**
 * @decription 存钱线程
 *
 */
class DepositThread2 extends Thread{
    private Account account;
    private double drawAmount=300;
    
    public DepositThread2(String name,Account account,double drawAmount) {
        super(name);
        this.account = account;
        this.drawAmount = drawAmount;
    }
    /* (non-Javadoc)
     * @see java.lang.Thread#run()
     */
    @Override
    public void run() {
        for(int i=0;i<5;i++){
            account.deposit(drawAmount);
        }
    }
}
/**
 * @decription 取钱线程
 *
 */
class DrawThread2 extends Thread{
    private Account account;
    private double drawAmount = 300;
    
    public DrawThread2(String name,Account account,double drawAmount) {
        super(name);
        this.account = account;
        this.drawAmount = drawAmount;
    }
    /* (non-Javadoc)
     * @see java.lang.Thread#run()
     */
    @Override
    public void run() {
        for(int i=0;i<5;i++){
            account.draw(drawAmount);
        }
    }
}



在存钱线程里使用循环存了5次钱,每次存后再等待取钱线程取钱. 从控制台的输出:只存了3次或4次, 并且程序偶尔不能结束.  
请问是不是死锁了, 要如何解决?

------解决方案--------------------
wait具有假唤醒线程的现象出现,因此要采用while来判断不是采用if
将存钱和取钱的if(flag)改为while(flag)逻辑请自己研究下。