首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

多线程,为什么会出现偶然并且异常的结果

2012-03-29 
多线程,为什么会出现偶然并且错误的结果Java code/** **/package thread/** * @description 线程同步 * *

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

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)逻辑请自己研究下。

热点排行