Java并发之:生产者消费者问题
生产者消费者问题是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并发之:生产者消费者问题的更多相关文章
- java并发之生产者消费者模型
生产者和消费者模型是操作系统中经典的同步问题.该问题最早由Dijkstra提出,用以演示它提出的信号量机制. 经典的生产者和消费者模型的描写叙述是:有一群生产者进程在生产产品.并将这些产品提供给消费者 ...
- Java并发程序设计(十一)设计模式与并发之生产者-消费者模式
设计模式与并发之生产者-消费者模式 生产者-消费者模式是一个经典的多线程设计模式.它为多线程间的协作提供了良好的解决方案.在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程. ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- java多线程解决生产者消费者问题
import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...
- java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】
java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...
- Java设计模式之生产者消费者模式
Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ...
- java多线程模拟生产者消费者问题,公司面试常常问的题。。。
package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...
- JAVA多线程之生产者 消费者模式 妈妈做面包案例
创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包 最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...
- Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)
生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...
随机推荐
- mongodb--java操作
一.mongodb客户端 mongodb提供诸多语言的客户端,也包括java的客户端.通过这些客户端,我们可以很方便地使用编写代码的方式对mongodb进行操作.这里使用java客户端进行示例.使用j ...
- 图解SQL的inner join、left join、right join、full outer join、union、union all的区别
转自:http://blog.csdn.net/jz20110918/article/details/41806611 假设我们有两张表.Table A 是左边的表.Table B 是右边的表.其各有 ...
- javascript之url转义escape()、encodeURI()和encodeURIComponent()
JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...
- poj 3667 Hotel(线段树,区间合并)
Hotel Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 10858Accepted: 4691 Description The ...
- 【温故而知新-Javascript】对象
1 创建对象 Javascript 支持对象的概率.有多种方法可以用来创建对象. <!DOCTYPE html> <html lang="en"> < ...
- 谷歌开源项目Google Preview Image Extractor(PIEX) (附上完整demo代码)
前天偶然看到谷歌开源项目中有一个近乎无人问津的项目Google Preview Image Extractor(PIEX) . 项目地址: https://github.com/google/piex ...
- HDU 2065 “红色病毒”问题 --指数型母函数
这种有限制的类棋盘着色问题一般可以用指数型母函数来解决,设Hn表示这样的着色数,首先H0=1,则Hn等于四个字母的(A,B,C,D)的多重集合的n排列数,其中每个字母的重数是无穷,且要求A,C出现的次 ...
- Spring AOP 注解和xml实现 --转载
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...
- java 21 - 13 IO流之 合并流
SequenceInputStream :表示其他输入流的逻辑串联. 构造方法摘要 SequenceInputStream(Enumeration<? extends InputStream&g ...
- android:ToolBar详解(手把手教程)
今年(2014) 的 google i/o 发表令多数人为之一亮的 material design,而 google 也从「google i/o 2014」 开始,大家也陆陆续续地看到其更新的 and ...