生产者-消费者【比较】
有两个版本的生产者-消费者,请高手看下都有什么问题!第一个:
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){
/**
*程序逻辑
*
*/
}
}
同上! 你要问什么? --------------------编程问答-------------------- 我的错,应该标示的。主要区别是在work方法中线程池的使用上(关闭线程池的问题),还有消费者的calc()方法上
--------------------编程问答-------------------- 想说啥,木有听懂 --------------------编程问答--------------------
补充:Java , Java EE