Java线程通信
假设现在系统中有两个线程,分别代表取钱和存钱,现在假设系统有一种特殊的要求,系统要求存款者和取款者不断重复存取款,而且要求每当存款者将钱存入指定账户时,取钱者就立即取出该笔钱,不允许连续存款两次,也不允许连续取款两次
- 实现思路
- 设置一个标识
- 当账户有钱时,存钱线程阻塞,并通知取钱线程取钱
- 当账户没有钱时,取钱线程阻塞,并通知存钱线程存钱
public class ThreadConnection {
public static void main(String[] args) {
Account1 account1 = new Account1("建行卡", 0);
new DepositThread("存钱者1",account1,800).start();
new DepositThread("存钱者2",account1,800).start();
new DrawThread("取钱者1",account1,800).start();
new DrawThread("取钱者2",account1,800).start();
new DrawThread("取钱者3",account1,800).start();
}
}
class Account1{
String accountNum;
int money;
//标识账户中是否有存款
boolean flag = false;
public Account1(String accountNum, int money) {
this.accountNum = accountNum;
this.money = money;
}
//取钱
public synchronized void draw(int drawMoney){
//如果没有钱则阻塞
if(!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
money-=drawMoney;
System.out.println(Thread.currentThread().getName()+"取走了"+drawMoney+"元");
System.out.println("账户剩余"+money+"元");
//取走了钱将标识设为false,并通知存钱
flag = false;
notifyAll();
}
}
//存钱
public synchronized void deposit(int depositMoney){
//如果账户有钱则让存钱方法阻塞
if(flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
money+=depositMoney;
System.out.println(Thread.currentThread().getName()+"存入了"+depositMoney+"元");
//存入了钱将标识设置为true,并通知取钱
flag = true;
notifyAll();
}
}
}
class DrawThread extends Thread{
Account1 account1;
int drawMoney;
public DrawThread(String name,Account1 account11,int drawMoney){
super(name);
this.account1 = account11;
this.drawMoney = drawMoney;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account1.draw(drawMoney);
}
}
}
class DepositThread extends Thread{
Account1 account1;
int depositMoney;
public DepositThread(String name,Account1 account11,int depositMoney){
super(name);
this.account1 = account11;
this.depositMoney = depositMoney;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account1.deposit(depositMoney);
}
}
}
运行结果:
由运行结果可知,两个存钱者随机向账户存入钱,三个取钱者随机取走账户中的钱,只有当取钱者取钱后,存钱者才能存钱,只有当存钱者存钱后,取钱者才能取钱。
程序最后被阻塞不能继续执行,只是由于两个存钱者有200次存钱操作,而三个取钱者有300次取钱操作,取钱操作一直在等待存钱,所以程序最后被阻塞。(此处不是死锁)