package net.liuyx.java;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
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));
// Start everything running by producing chassis:
exec.execute(new ChassisBuilder(chassisQueue));
TimeUnit.SECONDS.sleep(7);
exec.shutdownNow();
}
}
class Car2 {
private final int id;
private boolean engine = false, driveTrain = false, wheels = false;
public Car2(int idn) {
id = idn;
}
public Car2() {
this(-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<Car2> {
}
class ChassisBuilder implements Runnable {
private CarQueue carQueue;
private int counter = 0;
public ChassisBuilder(CarQueue cq) {
carQueue = cq;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
TimeUnit.MILLISECONDS.sleep(500);
// Make chassis:
Car2 c = new Car2(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 Car2 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 Car2 car() {
return car;
}
public CyclicBarrier barrier() {
return barrier;
}
@Override
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(); // Until the robots finish
// Put car into finishingQueue for further 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;
}
@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 pool;
public Robot(RobotPool p) {
pool = p;
}
public 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();
@Override
public void run() {
try {
powerDown(); // Wait until needed
while (!Thread.interrupted()) {
performService();
assembler.barrier().await(); // Synchronize
// We're done with that job...
powerDown();
}
} catch (InterruptedException e) {
System.out.println("Exiting " + this + " via interrupt");
} catch (BrokenBarrierException e) {
throw new RuntimeException(e);
}
System.out.println(this + " off");
}
private synchronized void powerDown() throws InterruptedException {
engage = false;
assembler = null;
// Put ourselves back in the available pool:
pool.release(this);
while (engage == false)
wait();
}
}
class EngineRobot extends Robot {
public EngineRobot(RobotPool pool) {
super(pool);
}
@Override
protected void performService() {
System.out.println(this + " install engine");
assembler.car().addEngine();
}
}
class DriveTrainRobot extends Robot {
public DriveTrainRobot(RobotPool pool) {
super(pool);
}
@Override
protected void performService() {
System.out.println(this + " install DriveTrain");
assembler.car().addDriveTrain();
}
}
class WheelRobot extends Robot {
public WheelRobot(RobotPool pool) {
super(pool);
}
@Override
protected void performService() {
System.out.println(this + " installing Wheels");
assembler.car().addWheels();
}
}
class RobotPool {
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();
return;
}
wait();
hire(robotType, d);
}
}
public synchronized void release(Robot r) {
add(r);
}
}
Java多线程——仿真生产汽车组装汽车过程
最新推荐文章于 2021-04-01 23:23:48 发布