生产者消费者问题是Java并发中的常见问题之一,在实现时,一般可以考虑使用juc包下的BlockingQueue接口,至于具体使用哪个类,则就需要根据具体的使用场景具体分析了。本文主要实现一个生产者消费者的原型,以及实现一个生产者消费者的典型使用场景。

第一个问题:实现一个生产者消费者的原型。

 import java.util.concurrent.*;

 class Consumer implements Runnable {
BlockingQueue q = null; public Consumer(BlockingQueue q) {
this.q = q;
} @Override
public void run() {
while(true) {
try {
q.take();
System.out.println("Consumer has taken a product.");
}catch(InterruptedException e) { }
}
}
} class Producer implements Runnable {
BlockingQueue q = null; public Producer(BlockingQueue q) {
this.q = q;
} @Override
public void run() {
while(true) {
try { // note that if there is any chance that block, usually we need a InterruptedException
q.put(new Object());
System.out.println("Producer has puted a product.");
}catch(InterruptedException e) { }
}
} } public class JC_ProducerConsumerPrototype {
static int queueCapacity = 1024;
//static BlockingQueue<Object> q = new ArrayBlockingQueue<Object>(queueCapacity); // Can also compile
static BlockingQueue q = new ArrayBlockingQueue(queueCapacity); // ABQ must has a capacity
public static void main(String[] args) {
Thread t1 = new Thread(new Producer(q));
Thread t2 = new Thread(new Consumer(q));
t1.start();
t2.start();
} }

第二个问题,现在假设生产者是在读取磁盘上的多个log文件,对于每一个文件,依次读取文件中的每一行,也就是一条log记录;消费者需要读取并分析这些记录,假设消费者是计算密集型的。如何在生产者消费者原型的基础上实现这些功能?

这个场景在server端开发中是经常碰到的,因为在Server端,不可避免地会产生大量的日志文件。

 import java.util.concurrent.*;
import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.util.*;
import java.nio.charset.*; class Producer implements Runnable {
BlockingQueue q = null;
String fileName = null;
CountDownLatch latch = null; public Producer(BlockingQueue q,String fileName,CountDownLatch latch) {
this.q = q;
this.fileName = fileName;
this.latch = latch;
} @Override
public void run() {
Path path = Paths.get(".",fileName);
try{
List<String> lines = Files.readAllLines(path,StandardCharsets.UTF_8);
for(int i=lines.size();i>0;i--){
try{
q.put(lines.get(i));
}catch(InterruptedException e) { }
}
}catch(IOException e){ }
latch.countDown();
}
} class Consumer implements Runnable {
BlockingQueue<String> q = null;
Boolean done = false; public Consumer(BlockingQueue q,Boolean done){
this.q = q;
this.done = done;
} @Override
public void run(){
while(!done||q.size()!=0){
try{
q.take();
}catch(InterruptedException e){ }
}
}
} public class JC_ProducerConsumerHandlingLog{
public static int fileCount = 1024;
public static String[] fileNames = new String[fileCount];
public static int cpuCount = 8;
public static CountDownLatch latch = new CountDownLatch(fileCount);
public static volatile boolean done = false;
public static BlockingQueue<String> q = new LinkedBlockingQueue<String>(fileCount);//one thread for one file public static void main(String[] args){
for(int i=0;i<fileCount;i++){
Thread t = new Thread(new Producer(q,fileNames[i],latch));
t.start();
}
for(int i=0;i<cpuCount;i++){//for computing tasks, we don't need too many threads.
Thread t = new Thread(new Consumer(q,done));
t.start();
}
try{
latch.await();
done = true;
}catch(InterruptedException e){ } }
}

需要稍微注意一下线程数的选择,对于计算密集型的任务,我认为线程数达到cpu的核数比较合理(在不考虑超线程的情况下,也就是说一个核只有一个线程)。有不同意见欢迎跟我交流!

Java并发之:生产者消费者问题的更多相关文章

  1. java并发之生产者消费者模型

    生产者和消费者模型是操作系统中经典的同步问题.该问题最早由Dijkstra提出,用以演示它提出的信号量机制. 经典的生产者和消费者模型的描写叙述是:有一群生产者进程在生产产品.并将这些产品提供给消费者 ...

  2. Java并发程序设计(十一)设计模式与并发之生产者-消费者模式

    设计模式与并发之生产者-消费者模式 生产者-消费者模式是一个经典的多线程设计模式.它为多线程间的协作提供了良好的解决方案.在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程. ...

  3. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  4. java多线程解决生产者消费者问题

    import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...

  5. java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】

    java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...

  6. Java设计模式之生产者消费者模式

    Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ...

  7. java多线程模拟生产者消费者问题,公司面试常常问的题。。。

    package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...

  8. JAVA多线程之生产者 消费者模式 妈妈做面包案例

    创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包  最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...

  9. Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)

    生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...

随机推荐

  1. 修改Tomcat服务器的端口号

    关键技术: Connector子元素下的port是设置服务器端口,而connection Timeout则是服务器连接超时单位为毫秒. 操作过程: (1)采用记事本打开Tomcat安装目录下的conf ...

  2. ASP.NET5 MVC6入门教学之一(自己动手)

    等待微软开源大动作已经好几年了,终于ASP.NET 5发布了.今天给新手们写一个简单地教程,教你认识一下ASP.NET5 MVC6 1.安装kvm 首先,你需要以管理员权限打开cmd,执行如下的脚本: ...

  3. CGI(通用网关接口)

    公共网关接口 CGI(Common Gateway Interface) 是WWW技术中最重要的技术之一,有着不可替代的重要地位.CGI是外部应用程序(CGI程序)与Web服务器之间的接口标准,是在C ...

  4. jquery获取复选框(checkbox)的选中值(一组和单个)

    使用jquery获取一组或者单个checkbox的选中状态的值.下面通过一个示例进行说明,假设现有一页面有一组checkbox的name的值为id,那么获取这组name=id的checkbox的值的方 ...

  5. 2014 Super Training #9 C E - Cup 2 --记忆化搜索

    原题:ZOJ 3681 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3681 题意:给一个m,n,m表示m个人,可以把m个 ...

  6. Spring 4.1+ 的 JSONP使用

    如今的巨石应用已经越来越不行了,很多互联网在后期都会在用分布式的架构 那么在页面上不同的服务调用不同域名下的json是有问题的 (跨域:不同域名,相同域名但是不同端口) JavaScript规范中提到 ...

  7. 关于codereview工具与建议

    http://www.ibm.com/developerworks/rational/library/11-proven-practices-for-peer-review/

  8. js判断滚动条到底部

    判断滚动条到底部,需要用到DOM的三个属性值,即scrollTop.clientHeight.scrollHeight. scrollTop为滚动条在Y轴上的滚动距离. clientHeight为内容 ...

  9. jquery中的get和set

    jquery中通过参数的个数来判断是get方法还是set方法: css: function(name, value ) { return value !== undefined ? jQuery.st ...

  10. 关于js中onclick字符串传参问题

    规则: 外变是“”,里面就是‘’外边是‘’,里边就是“”   示例: var a="111"; var html="<a onclick='selecthoods( ...