生産消費者のシミュレーション
Javaマルチスレッド技術を採用し、生産者と消費者の問題に合致するプログラムを設計して実現する.1つの対象(銃口)を操作し、その最大容量は12個の弾丸である.生産者スレッドは1つの圧入スレッドであり、銃口に絶えず弾丸を圧入する.消費者スレッドは1つの射出スレッドであり、銃口から絶えず弾丸を射出する.要求:(1)分析過程の説明を与える.(2)プログラム出力は、銃口に対する圧入と射出操作をシミュレートする.(3)プログラムを設計する際には,2つのスレッドの同期問題を考慮すべきである.
これは典型的な生産者消費という問題であり、同時にBlockingQueueでよく実現することができる.
Bullet,Shooter,BulletProductorの3つの内部クラスを持つGunクラスを作成します.
BulletProductorは弾丸の生産を担当し、弾丸の個数が12より大きい者は生産しない.
Shooterは射撃を担当し、弾丸を消費する.
具体的なコードは以下の通りです.
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シミュレーション射撃停止装弾停止
これは典型的な生産者消費という問題であり、同時にBlockingQueueでよく実現することができる.
Bullet,Shooter,BulletProductorの3つの内部クラスを持つGunクラスを作成します.
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シミュレーション射撃停止装弾停止