生产者消费者模式
题目描述:
采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。
对一个对象(枪膛)进行操作,其最大容量是10颗子弹(特别注意,射击和上膛也都是需要时间的!!!!!)。
生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,它不断从枪膛中射出子弹。
注意,答案中的Gun
(表示枪),ShoutTask
(表示射击线程的设计任务), LoadTask
(表示上膛线程的上膛任务),Test
(测试类)分别定义在不同的java
文件中
/**
*
* 表示枪
*/
public class Gun {
//枪膛中的子弹数
private int bullets;
/*
消费者线程(射击线程),调用该方法射击(消费子弹)
*/
public synchronized void shouting() {
if (bullets <= 0) {
//如果枪中没有子弹,则不射击
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//枪中有子弹,则射击
System.out.println(Thread.currentThread().getName()
+ "射出第" + bullets-- + "发子弹");
// 通知上膛线程,压入子弹
this.notifyAll();
}
}
/*
生产者线程调用该方法,上膛(压入子弹)
*/
public synchronized void loading() {
if (bullets >= 10) {
//如果枪膛中的子弹是满的,则不上膛
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//如果枪膛不满,则压入子弹
System.out.println(Thread.currentThread().getName() + "压入第" + ++bullets + "发子弹");
//模拟射击过程的时间延迟
this.notifyAll();
}
}
}
/**
*
* 生产者线程,不停的压入子弹
*/
public class LoadTask implements Runnable{
private Gun gun;
public LoadTask(Gun gun) {
this.gun = gun;
}
@Override
public void run() {
while (true) {
//模拟每次上膛过程的延迟
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
gun.loading();
}
}
}
/**
*
* 消费者线程执行的射击代码, 不停的射击
*/
public class ShoutTask implements Runnable {
private Gun gun;
public ShoutTask(Gun gun) {
this.gun = gun;
}
@Override
public void run() {
while (true) {
//模拟每次射击过程的延迟
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
gun.shouting();
}
}
}
/**
*
* 测试代码
*/
public class Test {
public static void main(String[] args) {
//射击线程和上膛线程操作的同一把枪
Gun gun = new Gun();
LoadTask loadTask = new LoadTask(gun);
ShoutTask shoutTask = new ShoutTask(gun);
new Thread(loadTask).start();
new Thread(shoutTask).start();
new Thread(loadTask).start();
new Thread(shoutTask).start();
}
}