可以使用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();
}
}
京公网安备 11010502036488号