可以使用wait(),nitify(),notifyAll()来进行线程协作,这三个方法必须由同步监视器来调用。

下列定义一个Account类。该类存、取钱交替进行。

public class Account {
    private String accountNo;
    private double balance;
    private boolean flag = false;
    public Account() {}
    public Account(String accountNo, double balance) {
        this.accountNo = accountNo;
        this.balance = balance;
    }
    public String getAccountNo() {
        return this.accountNo;
    }
    public void setAccountNo(String accountNo) {
        this.accountNo = accountNo;
    }
    public double getBalance() {
        return this.balance;
    }
    public synchronized void draw(double drawAmount) {
        try{
            if(!flag) {
                wait();
            } else {
                System.out.println(Thread.currentThread().getName()
                        + "draw" + drawAmount);
                flag = false;
                notifyAll();
            }
        } catch( InterruptedException e) {
            e.printStackTrace();
        }
    }
    public synchronized void deposit(double depositAmount) {
        try {
            if(flag) {
                wait();
            }
            else {
                System.out.println(Thread.currentThread().getName()
                        + "deposit" + depositAmount);
                flag = true;
                notifyAll();
            }
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((accountNo == null) ? 0 : accountNo.hashCode());
        long temp;
        temp = Double.doubleToLongBits(balance);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + (flag ? 1231 : 1237);
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Account other = (Account) obj;
        if (accountNo == null) {
            if (other.accountNo != null)
                return false;
        } else if (!accountNo.equals(other.accountNo))
            return false;
        if (Double.doubleToLongBits(balance) != Double
                .doubleToLongBits(other.balance))
            return false;
        if (flag != other.flag)
            return false;
        return true;
    }
}

每个存、取线程会分别执行100次存取款操作。

public class DrawThread extends Thread {
    private Account account;
    private double drawAmount;

    public DrawThread(String name, Account account, double drawAmount) {
        super(name);
        this.account = account;
        this.drawAmount = drawAmount;
    }

    public void run() {
        for (int i = 0; i < 100; i++) {
            account.draw(drawAmount);
        }
    }

}

public class DepositThread extends Thread {
    private Account account;
    private double depositAmount;

    public DepositThread(String name, Account account, double depositAmount) {
        super(name);
        this.account = account;
        this.depositAmount = depositAmount;
    }

    public void run() {
        for (int i = 0; i < 100; i++) {
            account.deposit(depositAmount);
        }
    }
}

下面执行一个测试类,看看效果。最后程序会阻塞,原因是取款线程100次取款操作执行完了,而取款者的线程还没有执行完取款操作,在一直等待被唤醒。

public class DrawTest {
    public static void main(String[] args) {
        Account account = new Account("wz123", 0);
        new DrawThread("drawer ", account, 800).start();
        new DepositThread("depositor A ", account, 800).start();
        new DepositThread("depositor B ", account, 800).start();
        new DepositThread("depositor C ", account, 800).start();

    }
}