仿真[汽车制造]

class Car{
	private final int id;
	private boolean 
		engine = false,
		driveTrain = false,
		wheels = false;
	
	public Car(int idn){
		id = idn;
	}
	public Car(){
		id = -1;
	}
	public synchronized int getId(){
		return id;
	}
	public synchronized void addEngine(){
		engine = true;
	}
	public synchronized void addDriveTrain(){
		driveTrain = true;
	}
	public synchronized void addWheels(){
		wheels = true;
	}
	public synchronized String toString(){
		return "Car " +id +"[ engine: " + engine
			+ " driveTrain: " + driveTrain + " wheels: "+ wheels+ " ]";
	}
}

class CarQueue extends LinkedBlockingQueue<Car>{}

class ChassisBuilder implements Runnable{
	private CarQueue carQueue;
	private int counter = 0;
	public ChassisBuilder(CarQueue cq){
		carQueue =cq;
	}
	public void run(){
		try {
			while(!Thread.interrupted()){
				TimeUnit.MILLISECONDS.sleep(500);
				Car c = new Car(counter++);
				System.out.println("ChassisBuilder created " +c);
				// Insert into queue
				carQueue.put(c);
			}
		} catch (InterruptedException e) {
			System.out.println("Interrupted: ChassisBuilder");
		}
		System.out.println("ChassisBuilder off");
	}
}

class Assembler implements Runnable{
	private CarQueue chassisQueue, finishingQueue;
	private Car car;
	private CyclicBarrier barrier = new CyclicBarrier(4);
	private RobotPool robotPool;
	public Assembler(CarQueue cq, CarQueue fq, RobotPool rp){
		chassisQueue = cq;
		finishingQueue = fq;
		robotPool = rp;
	}
	public Car car(){
		return car;
	}
	public CyclicBarrier barrier(){
		return barrier;
	}
	public void run(){
		try {
			while(!Thread.interrupted()){
				// Blocks until chassis is available;
				car = chassisQueue.take();
				// Hire robots to perform work;
				robotPool.hire(EngineRobot.class, this);
				robotPool.hire(DriveTrainRobot.class, this);
				robotPool.hire(WheelRobot.class, this);
				barrier.await();	// Unitl the robots finish
				// Put car into finishedQueue for futher work
				finishingQueue.put(car);
			}
		} catch (InterruptedException e) {
			System.out.println("Exiting Assembler via interrupt");
		} catch (BrokenBarrierException e) {
			// This one we want to know about
			throw new RuntimeException(e);
		}
		System.out.println("Assembler off");
	}
}

class Reporter implements Runnable{
	private CarQueue carQueue;
	public Reporter(CarQueue cq){
		carQueue = cq;
	}
	public void run(){
		try {
			while(!Thread.interrupted()){
				System.out.println(carQueue.take());
				System.out.println();
			}
		} catch (InterruptedException e) {
			System.out.println("Exiting Reporter via interrupt");
		}
		System.out.println("Reporter off");
	}
}

abstract class Robot implements Runnable{
	private RobotPool pool;
	public Robot(RobotPool p){
		pool = p;
	}
	protected Assembler assembler;
	public Robot assignAssembler(Assembler assembler){
		this.assembler = assembler;
		return this;
	}
	private boolean engage = false;
	public synchronized void engage(){
		engage = true;
		notifyAll();
	}
	// The part of run() that's different for each robot;
	abstract protected void performService();
	public void run(){
		try {
			powerDown();	// Wait unitll needed
			while(!Thread.interrupted()){
				performService();
				assembler.barrier().await();	// Synchronized
				// We're done with that job...
				powerDown();
			}
		} catch (InterruptedException e) {
			System.out.println("Exiting "+ this+ " via interrupt");
		} catch (BrokenBarrierException e) {
			// This one we want to know about
			throw new RuntimeException(e);
		}
		System.out.println(this +" off");
	}
	private synchronized void powerDown() throws InterruptedException{
		engage = false;
		assembler = null; // Disconnet from the Assembler;
		// Put ourserlves back in the available pool;
		pool.release(this);
		while(engage == false)	// Power down
			wait();
	}
	@Override
	public String toString() {
		return getClass().getName();
	}
}

class EngineRobot extends Robot{
	public EngineRobot(RobotPool pool){
		super(pool);
	}
	protected void performService(){
		System.out.println(this +" installing engine");
		assembler.car().addEngine();
	}
}

class DriveTrainRobot extends Robot{
	public DriveTrainRobot(RobotPool pool){
		super(pool);
	}
	protected void performService(){
		System.out.println(this+" installing DriveTrain");
		assembler.car().addDriveTrain();
	}
}

class WheelRobot extends Robot{
	public WheelRobot(RobotPool pool){
		super(pool);
	}
	protected void performService(){
		System.out.println(this + " installing Wheels");
		assembler.car().addWheels();
	}
}

class RobotPool{
	// Quietly prevents identical entries;
	private Set<Robot> pool = new HashSet<Robot>();
	public synchronized void add(Robot r){
		pool.add(r);
		notifyAll();
	}
	public synchronized void hire(Class<? extends Robot> robotType, 
			Assembler d) throws InterruptedException{
		for(Robot r : pool)
			if(r.getClass().equals(robotType)){
				pool.remove(r);
				r.assignAssembler(d);
				r.engage();	// Power it up to do the task
				return;
			}
		wait();	// None available
		hire(robotType, d);	// Try again, recursively
	}
	public synchronized void release(Robot r){
		add(r);
	}
}

public class CarBuilder {
	public static void main(String[] args) throws InterruptedException {
		CarQueue chassisQueue = new CarQueue(),
			finishingQueue = new CarQueue();
		ExecutorService exec = Executors.newCachedThreadPool();
		RobotPool robotPool = new RobotPool();
		exec.execute(new EngineRobot(robotPool));
		exec.execute(new DriveTrainRobot(robotPool));
		exec.execute(new WheelRobot(robotPool));
		exec.execute(new Assembler(chassisQueue, finishingQueue, robotPool));
		exec.execute(new Reporter(finishingQueue));
		// Start everything running by producing chassis;
		exec.execute(new ChassisBuilder(chassisQueue));
		TimeUnit.SECONDS.sleep(7);
		exec.shutdownNow();
	}
}
  Car 是经由CarQueue从一个地方传送到另一个地方的, CarQueue是一种LinkedBlockingQueue类型。 ChassisBuilder创建了一个未加修饰的Car, 并把它放到了一个CarQueue中。 Assembler从一个CarQueue中取走Car, 并雇请Robot对其加工。 CyclicBarrier使Assembler等待。直至所有的Robot都完成, 并且在那一时刻它会将Car放置到将离开CarQueue中,然后被传送 到下一个操作。最总的CarQueue的消费者是一个Report对象, 它只打印Car, 以显示所有的任务都已经正确的完成了。 Car将其所有方法都设置成了synchronized的。 正如它所表现出来的那样, 在本例中,这是多余的, 因为在工程的内部, Car是通过队列一动的, 并且在任何时, 只有一个任务能够在某辆车上工作。 基本上,队列可以强制串行化地访问Car。但是这正是你可能会落入的陷阱-- 你可能会说“让我们尝试着通过不对Car类同步来进行优化, 因为看起来 Car在这里并不需要同步。 但是当这个系统连接到另一个需要Car被同步 的系统时,它就会崩溃。 // 即Car可能会被多个线程使用,因此我们需要以明显的方式使其成为线程安全的

你可能感兴趣的:(制造)