分发工作
考虑一个假想的用于汽车的机器人组装线,每辆Car都将分多个阶段构建,从创建底盘开始,紧跟着是安装发动机、车厢和轮子。
package com21仿真;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;
/**
* Created by Panda on 2018/5/30.
*/
class Car{
private final int id;
private boolean engine=false ;
private boolean driveTrain=false ;
private boolean 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 carQueue) {
this .carQueue = carQueue;
}
@Override
public void run () {
try {
while (!Thread.interrupted()){
TimeUnit.MILLISECONDS.sleep(500 );
Car car = new Car(counter++);
System.out.println("ChassisBuilder created " +car);
carQueue.put(car);
}
}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 cyclicBarrier = new CyclicBarrier(4 );
private RobotPool robotPool;
public Assembler (CarQueue chassisQueue, CarQueue finishingQueue, RobotPool robotPool) {
this .chassisQueue = chassisQueue;
this .finishingQueue = finishingQueue;
this .robotPool = robotPool;
}
public Car car (){return car;}
public CyclicBarrier barrier (){return cyclicBarrier;}
@Override
public void run () {
try {
while (!Thread.interrupted()){
car=chassisQueue.take();
robotPool.hire(EngineRobot.class,this );
robotPool.hire(DriveTrainRobot.class,this );
robotPool.hire(WheelRobot.class,this );
barrier().await();
finishingQueue.put(car);
}
}catch (InterruptedException e){
System.out.println("Exiting Assembler cia interrupt" );
}catch (BrokenBarrierException e){
throw new RuntimeException();
}
System.out.println("Assembler off" );
}
}
class Reporter implements Runnable{
private CarQueue carQueue;
public Reporter (CarQueue carQueue) {
this .carQueue = carQueue;
}
@Override
public void run () {
try {
while (!Thread.interrupted()){
System.out.println(carQueue.take());
}
}catch (InterruptedException e){
System.out.println("Exiting Reporter via interrupt" );
}
System.out.println("Reporter off" );
}
}
abstract class Robot implements Runnable{
private RobotPool robotPool;
public Robot (RobotPool robotPool) {
this .robotPool = robotPool;
}
protected Assembler assembler;
public Robot assignAssembler (Assembler assembler){
this .assembler=assembler;
return this ;
}
private boolean engage=false ;
public synchronized void engage (){
engage=true ;
notifyAll();
}
abstract protected void performService ();
@Override
public void run () {
try {
powerDown();
while (!Thread.interrupted()){
performService();
assembler.barrier().await();
powerDown();
}
}catch (InterruptedException e){
System.out.println("Exiting " +this +"via interrupt" );
}catch (BrokenBarrierException e){
throw new RuntimeException();
}
System.out.println(this + "off" );
}
private synchronized void powerDown () throws InterruptedException{
engage=false ;
assembler=null ;
robotPool.release(this );
while (engage==false ) wait();
}
public String toString (){return getClass().getName();}
}
class EngineRobot extends Robot{
public EngineRobot (RobotPool robotPool) {
super (robotPool);
}
@Override
protected void performService () {
System.out.println(this +" installing engine" );
assembler.car().addEngine();
}
}
class DriveTrainRobot extends Robot{
public DriveTrainRobot (RobotPool robotPool) {
super (robotPool);
}
@Override
protected void performService () {
System.out.println(this + " installing DriveTrain" );
assembler.car().addDriveTrain();
}
}
class WheelRobot extends Robot{
public WheelRobot (RobotPool robotPool) {
super (robotPool);
}
@Override
protected void performService () {
System.out.println(this +" installing Wheels" );
assembler.car().addWheels();
}
}
class RobotPool{
private Set<Robot> pool=new HashSet<>();
public synchronized void add (Robot robot){
pool.add(robot);
notifyAll();
}
public synchronized void hire (Class<? extends Robot> robotType,Assembler assembler) throws InterruptedException{
for (Robot robot:pool){
if (robot.getClass().equals(robotType)){
pool.remove(robot);
robot.assignAssembler(assembler);
robot.engage();
return ;
}
}
wait();
hire(robotType,assembler);
}
public synchronized void release (Robot robot){add(robot);}
}
public class CarBuilder {
public static void main (String[] args) throws Exception {
CarQueue chassisQueue=new CarQueue();
CarQueue finishingQueue=new CarQueue();
ExecutorService executorService = Executors.newCachedThreadPool();
RobotPool robotPool= new RobotPool();
executorService.execute(new EngineRobot(robotPool));
executorService.execute(new DriveTrainRobot(robotPool));
executorService.execute(new WheelRobot(robotPool));
executorService.execute(new Assembler(chassisQueue,finishingQueue,robotPool));
executorService.execute(new Reporter(finishingQueue));
executorService.execute(new ChassisBuilder(chassisQueue));
TimeUnit.SECONDS.sleep(7 );
executorService.shutdownNow();
}
}
Car 经由CarQueue从一个地方传送到另一个地方。CarQueue是一种LinkedBlockingQueue类型。ChassisiBuilder创建了一个未加修饰的Car,并把它放到了一个CarQueue中。Assembler从一个CarQueue中取走Car,并雇请Robot对其加工。CyclicBarrier使Assembler等待,直至所有的Robot都完成,并且在那一时刻它会将Car防止到即将离开它的CarQueue中,然后传送给下一个操作。最终的CarQueue的消费者是一个Reporter对象,只是打印Car,以显示所有的任务都已经正确的完成了。 Robot是在池中管理的,当需要完成工作时,就会从池中雇请适当的Robot。在工作完成时,这个Robot会返回到池中。