`
woxiaoe
  • 浏览: 276700 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

生产消费者的模拟

    博客分类:
  • Java
阅读更多

采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。对一个对象(枪膛)进行操作,
 其最大容量是12颗子弹。生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,
它不断从枪膛中射出子弹。
 要求:
 (1)给出分析过程说明。
 (2)程序输出,要模拟体现对枪膛的压入和射出操作;
(3)设计程序时应考虑到两个线程的同步问题。

这是一道典型的生产者消费这问题,同时可以用BlockingQueue得到很好的实现。

创建一个Gun的类,其拥有Bullet,Shooter,BulletProductor三个内部类。

BulletProductor 负责生产子弹,挡子弹个数大于12者不生产。

Shooter 负责射击 即消耗子弹。

具体代码如下:

package exam.b;

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 4、	采用Java 多线程技术,设计实现一个符合生产者和消费者问题的程序。对一个对象(枪膛)进行操作,
 * 其最大容量是12颗子弹。生产者线程是一个压入线程,它不断向枪膛中压入子弹;消费者线程是一个射出线程,
 * 它不断从枪膛中射出子弹。
 * 	要求:
 * 	(1)给出分析过程说明。
 * 	(2)程序输出,要模拟体现对枪膛的压入和射出操作;
 * (2)设计程序时应考虑到两个线程的同步问题。

 * @author 小e
 *
 * 2010-5-27 下午07:39:26
 */
public class Gun {
	class Bullet{
		int id = bulletCounter++;
		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return "" + id;
		}
	}
	class Shooter implements Runnable{
		BlockingQueue<Bullet> bullets;
		Random r = new Random();
		Shooter(BlockingQueue<Bullet> bullets){
			this.bullets = bullets;
		}
		void shoot() throws InterruptedException{
			Bullet bullet = bullets.take();
			System.out.println("射出子弹:" + bullet + "---枪膛子弹数量:" + bullets.size());
		}
		@Override
		public void run() {
			try {
				while(!Thread.interrupted()){
					shoot();
					TimeUnit.MILLISECONDS.sleep(r.nextInt(1000));
				}
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
				System.out.println("停止射击");
			}
			
		}
		
	}
	class BulletProductor implements Runnable{
		BlockingQueue<Bullet> bullets;
		Random r = new Random();
		public BulletProductor(BlockingQueue<Bullet> bullets) {
			this.bullets = bullets;
		}
		public void product(){
			if(bullets.size() < BULLET_SIZE){//枪膛未满
				Bullet bullet = new Bullet();
				bullets.add(bullet);
				System.out.println("装入子弹:" + bullet + "---枪膛子弹数量:" + bullets.size());
			}
		}
		@Override
		public void run() {
			try {
				while(!Thread.interrupted()){
					product();
					TimeUnit.MILLISECONDS.sleep(r.nextInt(500));
				}
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
				System.out.println("停止装子弹");
			}
		}
		
	}
	static int bulletCounter = 0;
	static final int BULLET_SIZE = 12;
	BlockingQueue<Bullet> bullets;
	ExecutorService exec;
	Gun(ExecutorService exec){
		this.bullets = new LinkedBlockingQueue<Bullet>();
		this.exec = exec;
	}
	public void action(){
		exec.execute(new BulletProductor(bullets));
		exec.execute(new Shooter(bullets));
	}
	public static void main(String[] args) throws InterruptedException {
		ExecutorService exec = Executors.newCachedThreadPool();
		Gun gun = new Gun(exec);
		gun.action();
		TimeUnit.SECONDS.sleep(6);
		exec.shutdownNow();
		System.out.println("模拟结束");
	}
}

 

outPut:

射出子弹:0---枪膛子弹数量:0
装入子弹:0---枪膛子弹数量:0
装入子弹:1---枪膛子弹数量:1
装入子弹:2---枪膛子弹数量:2
装入子弹:3---枪膛子弹数量:3
射出子弹:1---枪膛子弹数量:2
装入子弹:4---枪膛子弹数量:3
装入子弹:5---枪膛子弹数量:4
射出子弹:2---枪膛子弹数量:3
装入子弹:6---枪膛子弹数量:4
装入子弹:7---枪膛子弹数量:5
射出子弹:3---枪膛子弹数量:4
装入子弹:8---枪膛子弹数量:5
装入子弹:9---枪膛子弹数量:6
射出子弹:4---枪膛子弹数量:5
装入子弹:10---枪膛子弹数量:6
装入子弹:11---枪膛子弹数量:7
射出子弹:5---枪膛子弹数量:6
装入子弹:12---枪膛子弹数量:7
装入子弹:13---枪膛子弹数量:8
装入子弹:14---枪膛子弹数量:9
射出子弹:6---枪膛子弹数量:8
射出子弹:7---枪膛子弹数量:7
装入子弹:15---枪膛子弹数量:8
射出子弹:8---枪膛子弹数量:7
装入子弹:16---枪膛子弹数量:8
装入子弹:17---枪膛子弹数量:9
装入子弹:18---枪膛子弹数量:10
射出子弹:9---枪膛子弹数量:9
装入子弹:19---枪膛子弹数量:10
射出子弹:10---枪膛子弹数量:9
装入子弹:20---枪膛子弹数量:10
装入子弹:21---枪膛子弹数量:11
装入子弹:22---枪膛子弹数量:12
射出子弹:11---枪膛子弹数量:11
模拟结束
停止射击
停止装子弹

0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics