java多线程同步示例,来自《疯狂java讲义》。通过synchronized,wait(),notify(),notifyAll()实现多线程同步与通信。假设现在系统中有两个线程,这两个线程分别代表存钱者和取钱者---现在假设系统有一种特殊的要求,系统要求存款者和取钱者不断地重复存钱、取钱动作,而且要求每当存款着将钱存入指定账户后,取钱者就立即取出这笔钱。不允许存款者连续两次存钱,也不允许取钱者连续两次取钱。程序中,通过一个旗标flag标识,本次账户操作是不是存款操作,以便下次操作可以探测。可类比:http://www.oschina.net/code/snippet_820500_44795
1.[代码]Account账户类,有取钱(drawBalance)和存钱(deposit)两个同步方法
package com.sunchp;
public class Account {
private String accountNo;
private double balance;
private boolean flag = false;
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 drawBalance(double drawBalance) {
if (flag) {
if (balance > drawBalance) {
System.out.println(Thread.currentThread().getName() + "取钱成功,正在吐钞:" + drawBalance);
balance -= drawBalance;
flag = false;
this.notifyAll();
System.out.println(Thread.currentThread().getName() + "余额为:" + getBalance());
} else {
System.out.println(Thread.currentThread().getName() + "取钱失败,余额不足");
}
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void deposit(double depositBalance) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + " 存款:" + depositBalance);
this.balance += depositBalance;
flag = true;
this.notifyAll();
System.out.println(Thread.currentThread().getName() + "余额为:" + getBalance());
}
}
}
2.[代码]取钱线程类
package com.sunchp;
public class MyThread1 implements Runnable {
private Account account;
private double drawBalance;
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public double getDrawBalance() {
return drawBalance;
}
public void setDrawBalance(double drawBalance) {
this.drawBalance = drawBalance;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.drawBalance(drawBalance);
}
}
}
3.[代码]存钱线程类
package com.sunchp;
public class MyThread2 implements Runnable {
private Account account;
private double depositBalance;
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public double getDepositBalance() {
return depositBalance;
}
public void setDepositBalance(double depositBalance) {
this.depositBalance = depositBalance;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.deposit(depositBalance);
}
}
}
4.[代码]测试类,main方法
package com.sunchp;
public class Test {
public static void main(String[] args) throws Exception {
Account acc = new Account("001", 1000);
MyThread1 mt1 = new MyThread1();
mt1.setAccount(acc);
mt1.setDrawBalance(20);
Thread t1 = new Thread(mt1, "取钱者1");
Thread t2 = new Thread(mt1, "取钱者2");
MyThread2 mt2 = new MyThread2();
mt2.setAccount(acc);
mt2.setDepositBalance(20);
Thread t3 = new Thread(mt2, "存钱者1");
Thread t4 = new Thread(mt2, "存钱者2");
t1.start();
t2.start();
t3.start();
t4.start();
}
}