多线程分工协作模板
在项目开发中遇到复杂任务使用单线程比较浪费时间效率也不高,使用多线程分解任务能提高执行效率。
首先定义一个产品接口
public interface Product {}
定义产品生产线
public class ProductLine extends LinkedBlockingDeque<Product> {}
定义抽象机器人
public abstract class Robot implements Runnable { private ReentrantLock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); private boolean engage = false; private RobotPool pool; protected Workshop shop; public Robot(RobotPool pool, Workshop shop) { this.pool = pool; this.shop = shop; } protected abstract void performService(Product product); @Override public void run() { this.lock.lock(); try { this.powerDown(); while (!Thread.interrupted() && this.engage) { this.performService(this.shop.getProduct()); this.powerDown(); } } catch (InterruptedException e) { System.out.println(this + " exit"); return ; } finally { this.lock.unlock(); } } private void powerDown() throws InterruptedException { this.lock.lock(); try { this.engage = false; this.pool.release(this); while (!this.engage) { this.condition.await(); } } finally { this.lock.unlock(); } } public void engage() { this.lock.lock(); try { this.engage = true; this.condition.signalAll(); } finally { this.lock.unlock(); } } }
定义机器人对象池
public class RobotPool { private Set<Robot> pool = new HashSet<Robot>(); private ReentrantLock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void add(Robot robot) { this.lock.lock(); try { this.pool.add(robot); this.condition.signalAll(); } finally { this.lock.unlock(); } } public void hire(Class<? extends Robot> robotType) { this.lock.lock(); try { for (Robot robot : this.pool) { if (robot.getClass().equals(robotType)) { this.pool.remove(robot); robot.engage(); return ; } } this.condition.await(); this.hire(robotType); } catch (InterruptedException e) { System.out.println("RobotPool exit"); return ; } finally { this.lock.unlock(); } } public void release(Robot robot) { this.add(robot); } }
定义生产车间
public class Workshop implements Runnable { private ProductLine baseLine; private ProductLine finishedLine; private CyclicBarrier barrier; private List<Class<? extends Robot>> robotTypes; private RobotPool pool; private Product product; public Workshop(ProductLine baseLine, ProductLine finishedLine, List<Class<? extends Robot>> robotTypes, RobotPool pool) { this.baseLine = baseLine; this.finishedLine = finishedLine; this.robotTypes = robotTypes; this.pool = pool; this.barrier = new CyclicBarrier(robotTypes.size() + 1); } @Override public void run() { try { while (!Thread.interrupted()) { this.product = this.baseLine.take(); for (Class<? extends Robot> type : this.robotTypes) { this.pool.hire(type); } this.barrier.await(); this.finishedLine.add(this.product); } } catch (InterruptedException e) { System.out.println("Workshop exit"); } catch (BrokenBarrierException e) { System.out.println("Workshop exit"); } } public Product getProduct() { return product; } public CyclicBarrier getBarrier() { return barrier; } }
测试模板
public class ThreadTest { public static class Person implements Product { private String name; private String age; private String sex; public String getName() { return name; } public synchronized void setName(String name) { this.name = name; } public synchronized String getAge() { return age; } public synchronized void setAge(String age) { this.age = age; } public synchronized String getSex() { return sex; } public synchronized void setSex(String sex) { this.sex = sex; } @Override public String toString() { return this.name + "," + this.age + "," + this.sex; } } public static class NameRobot extends Robot { public NameRobot(RobotPool pool, Workshop shop) { super(pool, shop); } @Override protected void performService(Product product) { Person person = (Person) product; Random rand = new Random(); switch (rand.nextInt(100) % 3) { case 0: person.setName("张三"); break; case 1: person.setName("李四"); break; case 2: person.setName("王五"); break; default: break; } try { this.shop.getBarrier().await(); } catch (InterruptedException e) { System.out.println(this + " exit"); } catch (BrokenBarrierException e) { System.out.println(this + " exit"); } } @Override public String toString() { return "NameRobot"; } } public static class AgeRobot extends Robot { public AgeRobot(RobotPool pool, Workshop shop) { super(pool, shop); } @Override protected void performService(Product product) { Person person = (Person) product; Random rand = new Random(); person.setAge("" + rand.nextInt(30)); try { this.shop.getBarrier().await(); } catch (InterruptedException e) { System.out.println(this + " exit"); } catch (BrokenBarrierException e) { System.out.println(this + " exit"); } } @Override public String toString() { return "AgeRobot"; } } public static class SexRobot extends Robot { public SexRobot(RobotPool pool, Workshop shop) { super(pool, shop); } @Override protected void performService(Product product) { Person person = (Person) product; Random rand = new Random(); person.setSex(0 == rand.nextInt(10) % 2 ? "女" : "男"); try { this.shop.getBarrier().await(); } catch (InterruptedException e) { System.out.println(this + " exit"); } catch (BrokenBarrierException e) { System.out.println(this + " exit"); } } @Override public String toString() { return "SexRobot"; } } public static class BuilderPerson implements Runnable { private ProductLine baseLine; public BuilderPerson(ProductLine baseLine) { this.baseLine = baseLine; } @Override public void run() { Person person = null; try { while (!Thread.interrupted()) { person = new Person(); this.baseLine.put(person); TimeUnit.MILLISECONDS.sleep(300); } } catch (InterruptedException e) { System.out.println("BuilderPerson exit"); } } } public static class Report implements Runnable { private ProductLine finished; public Report(ProductLine finished) { this.finished = finished; } @Override public void run() { Product product = null; try { while (!Thread.interrupted()) { product = this.finished.take(); System.out.println(product); } } catch (InterruptedException e) { System.out.println("Report exit"); } } } public static void main(String[] args) throws InterruptedException { ExecutorService exec = Executors.newCachedThreadPool(); RobotPool pool = new RobotPool(); ProductLine baseLine = new ProductLine(); ProductLine finishedLine = new ProductLine(); List<Class<? extends Robot>> types = new ArrayList<>(); types.add(NameRobot.class); types.add(AgeRobot.class); types.add(SexRobot.class); Workshop shop = new Workshop(baseLine, finishedLine, types, pool); exec.execute(new NameRobot(pool, shop)); exec.execute(new AgeRobot(pool, shop)); exec.execute(new SexRobot(pool, shop)); exec.execute(shop); exec.execute(new BuilderPerson(baseLine)); exec.execute(new Report(finishedLine)); TimeUnit.SECONDS.sleep(3); exec.shutdownNow(); } }
输出:
李四,2,男 张三,21,女 张三,1,女 李四,4,男 李四,16,女 王五,13,男 王五,4,男 张三,25,女 李四,7,女 李四,22,男 SexRobot exit AgeRobot exit Report exit BuilderPerson exit Workshop exit NameRobot exit
多写多线程程序,有助于培养面向对象编程的思想。保证每个线程流程的通畅,保证每个锁对象等待和通知齐备,保证线程调用锁对象的关系开闭一致。