面试:多线程,wait/notifyall 模拟枪的压弹和射击
面试题:
采用多线程技术,例如wait/notify,设计实现一个符合生产者和消费者问题的程序,对某一个对象(枪膛)进行操作,其最大容量是20颗子弹,生产者线程是一个压入线程,它不断向枪膛中压入子弹,消费者线程是一个射出线程,它不断从枪膛中射出子弹。
package com.example.demo.homework.concurrent.h2;
public abstract class AbstractGun {
/**
* 枪装弹
*/
abstract void zhuangdan();
/**
* 枪射击
*/
abstract void sheji();
}
package com.example.demo.homework.concurrent.h2;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Gun extends AbstractGun {
private static Log LOGGER = LogFactory.getLog(AbstractGun.class);
/**
* 子弹数量 枪内可以存放20颗子弹
*/
int bulletNum = 0;
@Override
synchronized void zhuangdan() {
try {
while (bulletNum >= 20) {
LOGGER.info("弹匣已满,无法装弹");
wait();
}
bulletNum++;
LOGGER.info("弹匣未满,开始装弹,现有子弹:" + bulletNum);
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
synchronized void sheji() {
try {
while (bulletNum <= 0) {
LOGGER.info("弹匣已空,无法射击");
wait();
}
LOGGER.info("弹匣有弹,开始射击,现有子弹:" + bulletNum);
bulletNum--;
LOGGER.info("射击完还剩子弹:" + bulletNum);
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.demo.homework.concurrent.h2;
import java.util.concurrent.TimeUnit;
/**
* 装弹类
*/
public class ZhuangDan implements Runnable {
private Gun gun;
public ZhuangDan() {
super();
}
public ZhuangDan(Gun gun) {
this.gun = gun;
}
@Override
public void run() {
while (true) {
gun.zhuangdan();
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.example.demo.homework.concurrent.h2;
import java.util.concurrent.TimeUnit;
public class Sheji implements Runnable {
private Gun gun;
public Sheji() {
}
public Sheji(Gun gun) {
this.gun = gun;
}
@Override
public void run() {
while (true) {
gun.sheji();
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.example.demo.homework.concurrent.h2;
public class RunMain {
public static void main(String[] args) {
Gun gun = new Gun();
Thread threadZhuangDan = new Thread(new ZhuangDan(gun));
threadZhuangDan.start();
Thread threadSheji = new Thread(new Sheji(gun));
threadSheji.start();
}
}
运行结果: