Java中線程之間需要一些協調通信,來共同完成一件任務。第一種方式使用條件變量:
package com.farsight.thread5;
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 accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public double getBalance() {
return balance;
}
// 設置取錢方法,因為賬戶余額不允許隨便修改,所以專門實現存款方法
public synchronized void draw(double drawAmount){
try{
// 如果flag 為假,表明賬戶沒有人存錢進去,取錢方法阻塞。
if(!flag){
wait();
}
else{
// 執行取錢操作
System.out.println(Thread.currentThread().getName()
+ " 取錢 :" + drawAmount);
balance -= drawAmount;
System.out.println("賬戶余額:" + balance);
// 將存款標識設為false
flag = false;
notifyAll();
}
}
catch(InterruptedException ex){
ex.printStackTrace();
}
}
// 設置存錢方法
public synchronized void deposit(double depositAmount){
try{
if(flag){
wait();
}
else{
// 執行存款操作
System.out.println(Thread.currentThread().getName() +
" 存款:" + depositAmount);
balance += depositAmount;
System.out.println("賬戶余額: " + balance);
// 將存款標識設為true
flag = true;
// 喚醒其他所有的線程
notifyAll();
}
}
catch(InterruptedException ex){
ex.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;
}
}
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);
}
}
}
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(){
// 重復執行100次存錢的方法
for(int i = 0; i < 100;i++){
account.deposit(depositAmount);
}
}
}
public class ThreadCommunicateDemon {
public static void main(String[] args) {
Account acct = new Account("1234567", 0);
new DrawThread("取錢者", acct, 1000).start();
new DepositThread("存錢者甲", acct, 1000).start();
new DepositThread("存錢者乙", acct, 1000).start();
new DepositThread("存錢者丙", acct, 1000).start();
}
}