案例
等待唤醒,生产者,消费者的问题
1 大炮发射装载
等待唤醒机制:
炮弹:数据
炮仗:操作数据的动作类
{
发射:如果有炮弹,那么发射,发射后唤醒装载者,如果没有就等待
装载:如果有炮弹那么等待,如果没有就装载,装载成功,唤醒发射者
}
装载者(生产者):不停的 调用 炮仗的 发射
发射者(消费者):不停的 调用 炮仗的 装载
怎么保证 每次发射者能发射?怎么保证每次装载者能够装载? 使用等待唤醒机制。
public class Cannon { // 炮
public int i = 0;// 计数行为
public Cannon(int i) {
this.i = i;
}
}
// 容器
public class Cartridge {
Cannon cannon = null;// 数据
// 填充
synchronized public void padding(Cannon cannon) {// this
// 如果没炮弹 那么当前线程被等待
if (this.cannon != null) { // 当前对象的cannon,而不是形参
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// System.out.println("------发射第"+cannon.i+"可炸弹");
this.cannon = cannon;// 填充
System.out.println("------填充第" + cannon.i + "炸弹成功");
System.out.println("-----唤醒发射者");
this.notify();
}
// 发射
synchronized public void launch() {
// 如果cannon 如果还有炮弹
if (cannon == null) {
try {
this.wait();// 自己被等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i = cannon.i;
this.cannon = null;// 赋值为 kong
System.out.println("*********发射了第" + i + "成功");
System.out.println("******唤醒填充者");
this.notify();
}
}
public class TestWaitNotify {
public static void main(String[] args) {
// 容器
Cartridge cartridge = new Cartridge();
// 生产者
ProducerPadding producerPadding = new ProducerPadding();
producerPadding.cartridge = cartridge; // 没有构造函数,就要手动赋值
// 消费者
ConsumerLaunch consumerLaunch = new ConsumerLaunch();
consumerLaunch.cartridge = cartridge;
producerPadding.start();
consumerLaunch.start();
}
}
// 生产者
class ProducerPadding extends Thread {
Cartridge cartridge;
@Override
public void run() {
for (int i = 1; true; i++) {
cartridge.padding(new Cannon(i));
}
}
}
// 消费者
class ConsumerLaunch extends Thread {
Cartridge cartridge;
@Override
public void run() {
for (int i = 1; true; i++) {
cartridge.launch();
}
}
}
运行结果:
2 生产者消费者
1.synchronized关键字,放在方法上,锁定调用那个方法的对象 可以保证线程安全,因为上锁了。
2.放在方法的内部,表示对某一个锁调用方法对象
参考一下我滴猪儿虫写的:
https://blog.csdn.net/weixin_42505605/article/details/91384090