- 浏览: 99990 次
- 性别:
- 来自: 上海
最新评论
-
karistino:
设定的进程数目不同时统计的关键字个数不一样
JAVA多线程读写文件范例 -
sd6292766:
在系统的服务进程中,找到“DCom Server Proces ...
报错com.jacob.com.ComFailException: Can't co-create object时, 另外的解决途径 -
zyh3380433:
怎么解决?????
报错com.jacob.com.ComFailException: Can't co-create object时, 另外的解决途径 -
sd6292766:
ribavnu 写道线程锁。求楼主继续霸气啊,来个把钱存到数据 ...
JAVA多线程的一个复习例子(取款同步)(希望大家不要看源代码,看题目自己写出实现) -
ribavnu:
线程锁。求楼主继续霸气啊,来个把钱存到数据库的,然后数据库实现 ...
JAVA多线程的一个复习例子(取款同步)(希望大家不要看源代码,看题目自己写出实现)
在写之前先声明,本文是基于之前在博客园网站上检索到的一份JAVA多线程读写文件的示例,我在写自己的程序时是在那位作者写的基础上做了改良,但已不记得原文的地址。如果有知情者,烦请帖出地址,我在此文上加入引用或转载。
本程序是基于这么一种考虑,某系统后台有个将近2G大小的日志文件,你用任何编辑器去打开它,都将会很困难。针对这样的大文件解析处理,解决方案是使用多个线程,分割读取指定的大文件。获取我们所需要的信息。不多说,上代码了,有注释可以帮助理解。
运行结果如下:
我用10个线程去解析金庸大师写的《倚天屠龙记》,“无忌”这个词在这部小说中一共出现了4722次。实在找不到再大一些的文件了。倚天屠龙记.txt的大小4M出头。
关于CountDownLatch类的作用说明:
在API文档中,已经说明是一个辅助类。用于控制主线程与子线程之间切换的一个工具类。用法网上去搜下。ITEYE里也有人讨论过。我在这里使用它解决这样的问题:在确保10个线程都完成文件的解析工作后,系统调用主线程做剩下该做的事情,即:输出“出现的次数”。不确保这点的话,会导致执行完第4个线程,后面的线程还没开始,系统已经做最后一步输出统计结果,这样就达不到我们要的效果。这里解决方案有另一个简单的,自己写个计数器,从10记到1,10个线程嘛。这个看个人喜好吧。
本程序是基于这么一种考虑,某系统后台有个将近2G大小的日志文件,你用任何编辑器去打开它,都将会很困难。针对这样的大文件解析处理,解决方案是使用多个线程,分割读取指定的大文件。获取我们所需要的信息。不多说,上代码了,有注释可以帮助理解。
package com.thread.multipl.mysolution; import java.io.IOException; import java.io.RandomAccessFile; import java.util.concurrent.CountDownLatch; /** * 这个线程用来读取文件,当获取到指定关键字时,在指定的对象加1 * @author 刘峰管理2 * */ public class ReadThread extends Thread{ //定义字节数组(取水的竹筒)的长度 private final int BUFF_LEN = 256; //定义读取的起始点 private long start; //定义读取的结束点 private long end; //将读取到的字节输出到raf中 randomAccessFile可以理解为文件流,即文件中提取指定的一部分的包装对象 private RandomAccessFile raf; //线程中需要指定的关键字 private String keywords; //此线程读到关键字的次数 private int curCount = 0; /** * jdk1.5开始加入的类,是个多线程辅助类 * 用于多线程开始前统一执行操作或者多线程执行完成后调用主线程执行相应操作的类 */ private CountDownLatch doneSignal; public ReadThread(long start, long end, RandomAccessFile raf,String keywords,CountDownLatch doneSignal){ this.start = start; this.end = end; this.raf = raf; this.keywords = keywords; this.doneSignal = doneSignal; } public void run(){ try { raf.seek(start); //本线程负责读取文件的大小 long contentLen = end - start; //定义最多需要读取几次就可以完成本线程的读取 long times = contentLen / BUFF_LEN+1; System.out.println(this.toString() + " 需要读的次数:"+times); byte[] buff = new byte[BUFF_LEN]; int hasRead = 0; String result = null; for (int i = 0; i < times; i++) { //之前SEEK指定了起始位置,这里读入指定字节组长度的内容,read方法返回的是下一个开始读的position hasRead = raf.read(buff); //如果读取的字节数小于0,则退出循环! (到了字节数组的末尾) if (hasRead < 0) { break; } result = new String(buff,"gb2312"); /// System.out.println(result); int count = this.getCountByKeywords(result, keywords); if(count > 0){ this.curCount += count; } } KeyWordsCount kc = KeyWordsCount.getCountObject(); kc.addCount(this.curCount); doneSignal.countDown();//current thread finished! noted by latch object! } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public long getStart() { return start; } public void setStart(long start) { this.start = start; } public long getEnd() { return end; } public void setEnd(long end) { this.end = end; } public RandomAccessFile getRaf() { return raf; } public void setRaf(RandomAccessFile raf) { this.raf = raf; } public int getCountByKeywords(String statement,String key){ return statement.split(key).length-1; } public int getCurCount() { return curCount; } public void setCurCount(int curCount) { this.curCount = curCount; } public CountDownLatch getDoneSignal() { return doneSignal; } public void setDoneSignal(CountDownLatch doneSignal) { this.doneSignal = doneSignal; } }
package com.thread.multipl.mysolution; import java.io.File; import java.io.RandomAccessFile; import java.util.concurrent.CountDownLatch; public class MultiReadTest { /** * 多线程读取文件测试 * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub final int DOWN_THREAD_NUM = 10;//起10个线程去读取指定文件 final String OUT_FILE_NAME = "d:\\倚天屠龙记.txt"; final String keywords = "无忌"; //jdk1.5线程辅助类,让主线程等待所有子线程执行完毕后使用的类, //另外一个解决方案:自己写定时器,个人建议用这个类 CountDownLatch doneSignal = new CountDownLatch(DOWN_THREAD_NUM); RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM]; try{ long length = new File(OUT_FILE_NAME).length(); System.out.println("文件总长度:"+length+"字节"); //每线程应该读取的字节数 long numPerThred = length / DOWN_THREAD_NUM; System.out.println("每个线程读取的字节数:"+numPerThred+"字节"); //整个文件整除后剩下的余数 long left = length % DOWN_THREAD_NUM; for (int i = 0; i < DOWN_THREAD_NUM; i++) { //为每个线程打开一个输入流、一个RandomAccessFile对象, //让每个线程分别负责读取文件的不同部分 outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw"); if (i != 0) { // // isArr[i] = new FileInputStream("d:/勇敢的心.rmvb"); //以指定输出文件创建多个RandomAccessFile对象 } if (i == DOWN_THREAD_NUM - 1) { // //最后一个线程读取指定numPerThred+left个字节 // System.out.println("第"+i+"个线程读取从"+i * numPerThred+"到"+((i + 1) * numPerThred+ left)+"的位置"); new ReadThread(i * numPerThred, (i + 1) * numPerThred + left, outArr[i],keywords,doneSignal).start(); } else { //每个线程负责读取一定的numPerThred个字节 // System.out.println("第"+i+"个线程读取从"+i * numPerThred+"到"+((i + 1) * numPerThred)+"的位置"); new ReadThread(i * numPerThred, (i + 1) * numPerThred, outArr[i],keywords,doneSignal).start(); } } }catch(Exception e){ e.printStackTrace(); } // finally{ // // } //确认所有线程任务完成,开始执行主线程的操作 try { doneSignal.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //这里需要做个判断,所有做read工作线程全部执行完。 KeyWordsCount k = KeyWordsCount.getCountObject(); // Map<String,Integer> resultMap = k.getMap(); System.out.println("指定关键字出现的次数:"+k.getCount()); } }
package com.thread.multipl.mysolution; /** * 统计关键字的对象 * @author 刘峰管理2 * */ public class KeyWordsCount { private static KeyWordsCount kc; private int count = 0; private KeyWordsCount(){ } public static synchronized KeyWordsCount getCountObject(){ if(kc == null){ kc = new KeyWordsCount(); } return kc; } public synchronized void addCount(int count){ System.out.println("增加次数:"+count); this.count += count; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } }
运行结果如下:
引用
文件总长度:2012606字节
每个线程读取的字节数:201260字节
Thread[Thread-0,5,main] 需要读的次数:787
Thread[Thread-1,5,main] 需要读的次数:787
Thread[Thread-2,5,main] 需要读的次数:787
Thread[Thread-3,5,main] 需要读的次数:787
Thread[Thread-4,5,main] 需要读的次数:787
Thread[Thread-5,5,main] 需要读的次数:787
Thread[Thread-6,5,main] 需要读的次数:787
Thread[Thread-7,5,main] 需要读的次数:787
Thread[Thread-8,5,main] 需要读的次数:787
Thread[Thread-9,5,main] 需要读的次数:787
增加次数:0
增加次数:146
增加次数:432
增加次数:539
增加次数:587
增加次数:717
增加次数:631
增加次数:467
增加次数:665
增加次数:538
指定关键字出现的次数:4722
每个线程读取的字节数:201260字节
Thread[Thread-0,5,main] 需要读的次数:787
Thread[Thread-1,5,main] 需要读的次数:787
Thread[Thread-2,5,main] 需要读的次数:787
Thread[Thread-3,5,main] 需要读的次数:787
Thread[Thread-4,5,main] 需要读的次数:787
Thread[Thread-5,5,main] 需要读的次数:787
Thread[Thread-6,5,main] 需要读的次数:787
Thread[Thread-7,5,main] 需要读的次数:787
Thread[Thread-8,5,main] 需要读的次数:787
Thread[Thread-9,5,main] 需要读的次数:787
增加次数:0
增加次数:146
增加次数:432
增加次数:539
增加次数:587
增加次数:717
增加次数:631
增加次数:467
增加次数:665
增加次数:538
指定关键字出现的次数:4722
我用10个线程去解析金庸大师写的《倚天屠龙记》,“无忌”这个词在这部小说中一共出现了4722次。实在找不到再大一些的文件了。倚天屠龙记.txt的大小4M出头。
关于CountDownLatch类的作用说明:
在API文档中,已经说明是一个辅助类。用于控制主线程与子线程之间切换的一个工具类。用法网上去搜下。ITEYE里也有人讨论过。我在这里使用它解决这样的问题:在确保10个线程都完成文件的解析工作后,系统调用主线程做剩下该做的事情,即:输出“出现的次数”。不确保这点的话,会导致执行完第4个线程,后面的线程还没开始,系统已经做最后一步输出统计结果,这样就达不到我们要的效果。这里解决方案有另一个简单的,自己写个计数器,从10记到1,10个线程嘛。这个看个人喜好吧。
发表评论
-
转载:常见数据库字段类型与java.sql.Types的对应
2013-08-08 15:34 1687今天工作时候,刚好碰到类型转换错误的现象。找到一篇这样的列表文 ... -
maven+eclipse3.7+web工程开发+tomcat7.0搭环境的一些心得
2013-02-20 19:50 3734开头第一句话,过程真的很累,现在还存在一些细节问题。因 ... -
eclipse下使用ORACLE11GR1运行项目的一个要点记录
2013-02-20 00:06 1510参考资料:http://www.cnblogs.com ... -
报错com.jacob.com.ComFailException: Can't co-create object时, 另外的解决途径
2012-12-12 17:08 20308对于JAVA在调用打印控件jacob时,会出现这样的报错提示。 ... -
转载:maven Nexus入门指南
2012-12-02 23:38 1055因本人电脑故障,需要重启,特地用博客记下地址,方便下次学习 ... -
转载:JAVA开发人员成长路线
2012-11-18 17:24 1328转载地址:http://samter.it ... -
转载: 从JAVA多线程理解到集群分布式和网络设计的浅析
2012-10-25 23:58 1518转载地址:http://blog.csdn.net/tujiy ... -
mysql一个怪现象,百思不得其解
2012-10-03 17:42 820今天在JBOSS上配置JMS时,需要配置MYSQL 的 ... -
今天安装了apache服务器
2012-09-28 15:23 904今天因为我机器搭环境需要,安装了APACHE服务器 ... -
spring rmi的记录,转载的,吃完饭等下自己要用
2012-09-22 13:33 942http://blog.csdn.net/j2ee_dev/a ... -
Spring的JdbcTemplate做个简单记录,方便记忆
2012-09-16 17:50 960调用jdbcTemplate的UPDATE方法时,返回 ... -
转载:软件工程术语英语表达
2012-07-20 13:51 1204这里记录一下,常用的建模工具都是英文版的,这样方便校对 ... -
LOG4J工作中的一些个人收获
2012-06-21 23:38 1454继上一篇LOG4J一些工作中的学习总结之后,今天我在程序调试过 ... -
LOG4J一些工作中的学习总结
2012-06-20 12:19 1138首先声明:我这里使用的是apache的log4j日志框 ... -
转载:oschina网站的架构
2012-06-13 13:20 1449OsChina.NET 这个域名是在2008年8月16日申请的 ... -
转载:JFREECHART初级教程
2012-05-20 00:21 883JFreeChart是一组功能强大、灵活易用的Java绘图AP ... -
JS用open方法传中文乱码的解决方案,经测试,有效
2010-11-30 17:11 1245首先,在前台调用open打开对话框的位置,对要传值的中 ... -
JDK1.6存在一个方法错误,大家一起来交流下
2010-09-03 15:49 890今天在公司做项目时,用到这么一个功能:需要批量执行一些 ... -
JAVA多线程的探讨(收藏)
2010-08-07 22:30 942探索并发编程(一)------操作系统篇 探索并发编程(二) ... -
Ibatis初学的一个例子,新手可以尽快上手。
2010-06-25 17:28 1298IBATIS是优秀的半ORM框架,原先一直在用HIBE ...
相关推荐
JAVA 范例大全 光盘 资源 书籍目录: 前言. 第1章 开发环境搭建 1 实例1 下载、安装并配置JDK 1 实例2 第一个Java程序 3 实例3 在Eclipse中创建第一个Java程序 4 常见问题 javac不是内部或者外部命令 6 常见...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,...
实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 卡车和卡车司机之间的关系 229...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,...
实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 卡车和卡车司机之间的关系 229...
实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 ...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术...
实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 卡车和...
实例147 随机读写Java类文件 221 第3篇 Java面向对象编程 第8章 面向对象(教学视频:72分钟) 226 8.1 类 226 实例148 简单的通讯录类 226 实例149 简单的长度单位转换类 227 实例150 卡车和卡车司机之间的...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义...
Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密 Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义...
读写操作 当前目录-cd和pwd 使用glob来匹配文件名 exit和pid命令 环境变量 registry命令 第2部分tcl高级特性 第10章 引用问题与eval 使用list命令来构建代码 在eval内部利用concat uplevel命令 subst命令...
读写搜索 基础教程 RSS Web2.0时代,RSS你会用了吗?(技术实现总结) 知识集锦:三分钟全面了解 Blog 和 RSS C#+ASP.NET开发基于Web的RSS阅读器 ASP.NET RSS Toolkit(RSS工具) Serialize Your Deck with Positron ...