多线程分工协作模板

在项目开发中遇到复杂任务使用单线程比较浪费时间效率也不高,使用多线程分解任务能提高执行效率。

首先定义一个产品接口

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

多写多线程程序,有助于培养面向对象编程的思想。保证每个线程流程的通畅,保证每个锁对象等待和通知齐备,保证线程调用锁对象的关系开闭一致。

posted @ 2018-07-10 14:47  huanStephen  阅读(279)  评论(0编辑  收藏  举报