生产者消费者问题是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. Nodejs断言测试

    var assert = require('assert');/*node中,我们可以使用assert模块来测试代码.equal()和notEqual()分别作相等性和不等性的判断,第一个参数是期望值 ...

  2. tomcat 部署脚本

    将一下3个脚本放到一个目录里,做成一个 python 的包即可使用 脚本介绍 操作服务脚本 #!/usr/bin/env python # _*_coding:utf-8_*_ # Author: & ...

  3. Elasticsearch Scripts disabled

    Es 2.2版本中,在查询语句中使用script 时,提示如下错误 scripts of type [inline], operation [aggs] and lang [groovy] are d ...

  4. 卡拉兹(Callatz)猜想

    题目描述 卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步 得到n=1.卡拉兹在195 ...

  5. [转]WCDMA系统结构及关键技术

    本文转自:http://blog.csdn.net/lele52141/article/details/8498951 WCDMA系统结构: CN指核心网,UTRAN接入网,UE用户设备. UTRAN ...

  6. volatile与synchronized关键字

    volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatil ...

  7. 该怎么快速完成ZBrush中脸部的雕刻

    骨骼,是一门基础艺术,几百年来一直为伟大的艺术大师所研究,它曾经,也将一直是创作现实且可信角色的关键,提高骨骼知识更将大大提高雕刻技能. 若有疑问可直接访问:http://www.zbrushcn.c ...

  8. Chrome浏览器与常用插件推荐

    Chrome浏览器与常用插件推荐 官方chrome下载:http://www.google.cn/chrome/ 提示:需要FQ才能安装. 1,AdBlock 谷歌屏蔽广告: https://chro ...

  9. Android系列之UI组件----Menu菜单

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  10. 第16章 Windows线程栈

    16.1 线程栈及工作原理 (1)线程栈简介 ①系统在创建线程时,会为线程预订一块地址空间(即每个线程私有的栈空间),并调拨一些物理存储器.默认情况下,预订1MB的地址空间并调拨两个页面的存储器. ② ...