不能用if
不能用while
用变量做出来
学到后面把前面的只是丢了
不需要它一次全部性显示出来😩
做到这里,我就蒙了
这些很基础的,应该边学边练,平时多练习,自然就不会丢了。
1、一个人存钱,一个人取钱:在卡中没钱的时候存钱,有钱的时候取钱,交替执行
flag为true时:只能取钱,存钱会被阻塞
flag为false时:只能存钱,取钱会被阻塞
public class BankCard {
private double money;
// true:只能取钱
private boolean flag;
public synchronized void save(double addMoney) {
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
money += addMoney;
System.out.println(Thread.currentThread().getName() + " 存了:" + addMoney + " 余额:" + money);
flag = true;
this.notify();
}
public synchronized void take(double takeMoney) {
if (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
money -= takeMoney;
System.out.println(Thread.currentThread().getName() + " 取了:" + takeMoney + " 余额:" + money);
flag = false;
this.notify();
}
}
public class AddMoney implements Runnable{
BankCard bankCard;
public AddMoney() {
}
public AddMoney(BankCard bankCard) {
this.bankCard = bankCard;
}
@Override
public void run() {
for(int i = 0; i < 10; i++) {
bankCard.save(1000);
}
}
}
public class TakeMoney implements Runnable{
BankCard bankCard;
public TakeMoney() {
}
public TakeMoney(BankCard bankCard) {
this.bankCard = bankCard;
}
@Override
public void run() {
for(int i = 0; i < 10; i++) {
bankCard.take(1000);
}
}
}
public class BankTest {
public static void main(String[] args) {
BankCard bankCard = new BankCard();
AddMoney addMoney = new AddMoney(bankCard);
TakeMoney takeMoney = new TakeMoney(bankCard);
Thread thread1 = new Thread(addMoney, "男");
Thread thread2 = new Thread(takeMoney, "女");
thread1.start();
thread2.start();
}
}
结果
存取交替执行,没有问题
男 存了:1000.0 余额:1000.0
女 取了:1000.0 余额:0.0
男 存了:1000.0 余额:1000.0
女 取了:1000.0 余额:0.0
……
2、将线程数量增加到 4 个,两个存钱,两个取钱
public class BankTest {
public static void main(String[] args) {
BankCard bankCard = new BankCard();
AddMoney addMoney = new AddMoney(bankCard);
TakeMoney takeMoney = new TakeMoney(bankCard);
Thread producerA = new Thread(addMoney, "生产者A");
Thread producerB = new Thread(takeMoney, "生产者B");
Thread customerA = new Thread(takeMoney, "消费者A");
Thread customerB = new Thread(takeMoney, "消费者B");
producerA.start();
producerB.start();
customerA.start();
customerB.start();
}
}
结果
结果为乱序执行,而且最终形成死锁
生产者A 存了:1000.0 余额:1000.0
消费者A 取了:1000.0 余额:0.0
生产者A 存了:1000.0 余额:1000.0
生产者B 存了:1000.0 余额:2000.0
......
原因
解决
将存钱和取钱的判断语句 if 修改为 while 后
while (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
结果
生产者A 存了:1000.0 余额:1000.0
消费者B 取了:1000.0 余额:0.0
生产者A 存了:1000.0 余额:1000.0
消费者B 取了:1000.0 余额:0.0
————————然后形成了死锁,程序卡在这里…
原因
生产者A抢到CPU,存钱成功,修改标记为true,唤醒空,(阻塞队列:)
生产者B抢到CPU,不能存,进入阻塞队列……释放CPU和锁,(阻塞队列:生产者B)
生产者A抢到CPU,不能存,进入阻塞队列……释放CPU和锁,(阻塞队列:生产者B、生产者A)
消费者A抢到CPU,取钱成功,修改标记为false,唤醒生产者A,(阻塞队列:生产者B)
消费者B抢到CPU,不能取,进入阻塞队列……释放CPU和锁,(阻塞队列:生产者B、消费者B)
消费者A抢到CPU,不能取,进入阻塞队列……释放CPU和锁,(阻塞队列:生产者B、消费者B、消费者A)
生产者A抢到CPU,存钱成功,修改标记为true,释放CPU和锁,唤醒生产者B(阻塞队列:消费者B、消费者A)
生产者B抢到CPU,不能存,进入阻塞队列……释放CPU和锁,(阻塞队列:消费者B、消费者A、生产者B)
生产者A抢到CPU,不能存,进入阻塞队列……释放CPU和锁,(阻塞队列:消费者B、消费者A、生产者B、生产者A)
此时四个线程都进入了阻塞队列中,没有可以唤醒的线程了,所以就形成了死锁
解决
public synchronized void save(double addMoney) {
while (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
money += addMoney;
System.out.println(Thread.currentThread().getName() + " 存了:" + addMoney + " 余额:" + money);
flag = true;
this.notifyAll();
}
结果
生产者先存钱,然后消费者取钱,交替执行
生产者A 存了:1000.0 余额:1000.0
消费者B 取了:1000.0 余额:0.0
生产者B 存了:1000.0 余额:1000.0
消费者A 取了:1000.0 余额:0.0
生产者B 存了:1000.0 余额:1000.0
消费者B 取了:1000.0 余额:0.0
......
用switch语句判断字符z,根据z的不同,在case下作不同运算,就不会一下子加减乘除全显示出来,你这段代码,相当于完全没有用到z