当前位置:编程学习 > JAVA >>

生产者-消费者【比较】

有两个版本的生产者-消费者,请高手看下都有什么问题!
第一个:
public class Worker {
 
    //计算线程数
    private int consumerNum = 3;

    //队列长度
    private int queueSize = 10000;

    private BlockingQueue<Product> productQueue = new LinkedBlockingQueue<Product>(queueSize);  //存放product的队列
//生产者
    class ProductProducer implements Runnable {
        public ProductProducer() {
        }
        
        @Override
        public void run() {
//从数据库中取产品
            List<Product> products = productDAO.getGeneralProducts(_params);
            try {
                for(Product product:products){
                    productQueue.put(product);
                }
            } catch (InterruptedException e) {
                logger.error("ProductProducer.InterruptedException",e);  //To change body of catch statement use File | Settings | File Templates.
            } finally {
                Product p = new Product();
                p.setWid("end");
                try {
                    productQueue.put(p);
                } catch (InterruptedException e) {
                    logger.error("-------插入结束标志失败",e);
                }
            }
            logger.info("生产者线程");
        }

    }
//消费者
    class ProductCustomer implements Runnable {
        
        @Override
        public void run() {
            calc();
        }
     
        private void calc() {
            try {
while (true){
                    final Product product = productQueue.take();
                    if(product.getWid().equals("end")){
                        break;
                    }
                    long start = System.currentTimeMillis();
                    save(product);
                    logger.info("计算,耗时:"+(System.currentTimeMillis() - start));
                }
            } catch (Exception e) {
                logger.error("计算error", e);
            }
        }
    }

    public void work() {
        ExecutorService service = Executors.newFixedThreadPool(consumerNum + 1);
        service.submit(new ProductProducer());
for (int i = 0; i < consumerNum; i++) {
            service.submit(new ProductCustomer());
        }
    }

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("****.xml");
        Worker job
                = (Worker) context.getBean("***Worker");
//以上是从Spring拿到本类的实例,以调用work方法
        System.out.println("启动计算");
        job.work();

    }

    public void save(Product product){
        /**
*程序逻辑
*
*/
    }
}

第二个:
public class Worker {
 
    //计算线程数
    private int consumerNum = 3;

    //队列长度
    private int queueSize = 10000;

    private BlockingQueue<Product> productQueue = new LinkedBlockingQueue<Product>(queueSize);  //存放product的队列
//生产者
    class ProductProducer implements Runnable {
        public ProductProducer() {
        }
        
        @Override
        public void run() {
//从数据库中取产品
            List<Product> products = productDAO.getGeneralProducts(_params);
            try {
                for(Product product:products){
                    productQueue.put(product);
                }
            } catch (InterruptedException e) {
                logger.error("ProductProducer.InterruptedException",e);  //To change body of catch statement use File | Settings | File Templates.
            } finally {
                Product p = new Product();
                p.setWid("end");
                try {
                    productQueue.put(p);
                } catch (InterruptedException e) {
                    logger.error("-------插入结束标志失败",e);
                }
            }
            logger.info("生产者线程");
        }

    }
//消费者
    class ProductCustomer implements Runnable {
        private Product product;
        ProductCustomer(Product product) {
            this.product = product;
        }

        @Override
        public void run() {
            calc();
        }
     
        private void calc() {
            try {
                long start = System.currentTimeMillis();
                save(product);
                logger.info("计算,耗时:"+(System.currentTimeMillis() - start));
            } catch (Exception e) {
                logger.error("计算error", e);
            }
        }
    }

    public void work() {
        ExecutorService service = Executors.newFixedThreadPool(consumerNum + 1);
        service.submit(new ProductProducer());
        while (true){
            try {
                Product product = productQueue.take();
                if(product.getWid().equals("end")){
                    break;
                } else {
                    service.submit(new ProductCustomer(product));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        service.shutdown();          //关闭线程池
    }

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("****.xml");
        Worker job
                = (Worker) context.getBean("***Worker");
//以上是从Spring拿到本类的实例,以调用work方法
        System.out.println("启动计算");
        job.work();

    }

    public void save(Product product){
        /**
*程序逻辑
*
*/
    }
}
--------------------编程问答-------------------- 最好问的具体一点,不然谁闲的看你这么长的代码。。。 --------------------编程问答--------------------
引用 1 楼  的回复:
最好问的具体一点,不然谁闲的看你这么长的代码。。。



同上!  你要问什么? --------------------编程问答-------------------- 我的错,应该标示的。主要区别是在work方法中线程池的使用上(关闭线程池的问题),还有消费者的calc()方法上
引用 2 楼  的回复:
引用 1 楼  的回复:
最好问的具体一点,不然谁闲的看你这么长的代码。。。



同上!  你要问什么?
--------------------编程问答-------------------- 想说啥,木有听懂 --------------------编程问答--------------------
补充:Java ,  Java EE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,