子弹射击
Problem Description
采用Java线程计数实现一个射击场景的生产者消费者程序:每上膛一颗就射击一颗。
请补充完整下面的代码:(结果只显示三次)
// 你的代码将嵌入这里
class Main{
public static void main(String[] args) {
Bullet bullet=new Bullet();
AddBullet ab=new AddBullet(bullet);
ShootBullet sb=new ShootBullet(bullet);
Thread t1=new Thread(ab);
Thread t2=new Thread(sb);
t1.start();
t2.start();
}
}
Output Description
lock and load~~~~
fire!!!
lock and load~~~~
fire!!!
lock and load~~~~
fire!!!
解题代码
// Bullet 类
class Bullet {
// isLoad 是否上膛
private boolean isLoad = false;
// count 射击次数
private int count = 0;
// set get方法
public boolean isLoad() {
return isLoad;
}
public void setLoad(boolean load) {
isLoad = load;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
// AddBullet类 相当于生产者线程 实现Runnable接口
class AddBullet implements Runnable {
// bullet成员 子弹
private Bullet bullet = null;
// 构造方法
public AddBullet(Bullet bullet) {
this.bullet = bullet;
}
// 实现run方法 线程启动之后 会执行run方法
@Override
public void run() {
// 循环
while (true) {
// 同步代码块
synchronized (bullet) {
// 如果 子弹没有上膛 并且 射击次数小于等于2 count从0开始
if (!bullet.isLoad() && bullet.getCount() <= 2) {
// 打印信息
System.out.println("lock and load~~~~");
// 将子弹设置为上膛状态
bullet.setLoad(true);
}
// 唤醒其它线程(消费者线程)
bullet.notifyAll();
try {
// 如果射击次数大于2 代表已经射击了3次 0 1 2
if (bullet.getCount() > 2) {
// 跳出循环
break;
// 如果没有射击3次
} else {
// 调用wait方法 释放锁并使当前执行线程处于等待状态
bullet.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
// ShootBullet类 相当于消费者线程 实现Runnable接口
class ShootBullet implements Runnable {
// bullet 成员 子弹
private Bullet bullet = null;
// 构造方法
public ShootBullet(Bullet bullet) {
this.bullet = bullet;
}
// 实现run方法
@Override
public void run() {
// 循环
while (true) {
// 同步代码块
synchronized (bullet) {
// 如果 子弹已经上膛 并且 射击次数小于等于2
if (bullet.isLoad() && bullet.getCount() <= 2) {
// 打印信息
System.out.println("fire!!!");
// 将射击次数加1
bullet.setCount(bullet.getCount() + 1);
// 将子弹设置为未上膛状态
bullet.setLoad(false);
}
// 唤醒其它所有线程(生产者线程)
bullet.notifyAll();
try {
// 如果射击次数大于2 代表已经射击了3次 0 1 2
if (bullet.getCount() > 2) {
// 跳出循环
break;
// 如果没有射击3次
} else {
// 调用wait方法 释放锁并使当前执行线程处于等待状态
bullet.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}