package com.net.thread.future;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /**
* @author
* @Time:2017年8月16日 下午5:26:37
* @version 1.0
* @description
*/
public class CallableDemo3 { final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static void main(String[] args)
{
File f = new File("C://Users//LENOVO//Desktop//file");
// 文件总数
final List<File> filePathsList = new ArrayList<File>();
File[] filePaths = f.listFiles();
for (File s : filePaths) {
filePathsList.add(s);
} CountDownLatch latch = new CountDownLatch(filePathsList.size());
ExecutorService pool = Executors.newFixedThreadPool(10); BlockingQueue<Future<Map<String, FileInputStream>>> queue =
new ArrayBlockingQueue<Future<Map<String, FileInputStream>>>(100); System.out.println("-------------文件读、写任务开始时间:" + sdf.format(new Date()));
for (int i = 0; i < filePathsList.size(); i++) {
File temp = filePathsList.get(i);
Future<Map<String, FileInputStream>> future = pool.submit(new MyCallableProducer(latch, temp));
queue.add(future); pool.execute(new MyCallableConsumer(queue));
} try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------------文件读、写任务结束时间:" + sdf.format(new Date()));
pool.shutdownNow();
} // 文件读线程
static class MyCallableProducer implements Callable<Map<String, FileInputStream>>
{
private CountDownLatch latch;
private File file;
private FileInputStream fis = null;
private Map<String, FileInputStream> fileMap = new HashMap<String, FileInputStream>(); public MyCallableProducer(CountDownLatch latch, File file)
{
this.latch = latch;
this.file = file;
} @Override
public Map<String, FileInputStream> call() throws Exception
{
System.out.println(Thread.currentThread().getName() + " 线程开始读取文件 :" + file.getName() + " ,时间为 "+ sdf.format(new Date()));
fis = new FileInputStream(file);
fileMap.put(file.getName(), fis);
doWork();
System.out.println(Thread.currentThread().getName() + " 线程读取文件 :" + file.getName() + " 完毕" + " ,时间为 "+ sdf.format(new Date()));
latch.countDown();
return fileMap;
} private void doWork()
{
        //此方法可以添加一些业务逻辑,比如包装pojo等等操作,返回的值可以是任何类型
Random rand = new Random();
int time = rand.nextInt(10) * 1000;
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} // 文件写线程
static class MyCallableConsumer implements Runnable
{
private String fileName = "";
private BlockingQueue<Future<Map<String, FileInputStream>>> queue;
private FileInputStream fis = null;
private File dirFile = null; private BufferedReader br = null;
private InputStreamReader isr = null;
private FileWriter fw = null;
private BufferedWriter bw = null; public MyCallableConsumer(BlockingQueue<Future<Map<String, FileInputStream>>> queue2)
{
this.queue = queue2;
} @Override
public void run()
{
try {
Future<Map<String, FileInputStream>> future = queue.take();
Map<String, FileInputStream> map = future.get(); Set<String> set = map.keySet();
for (Iterator<String> iter = set.iterator(); iter.hasNext();) { fileName = iter.next().toString();
fis = map.get(fileName); System.out.println(Thread.currentThread().getName() + " 线程开始写文件 :" + fileName + " ,时间为 "+ sdf.format(new Date()));
try {
isr = new InputStreamReader(fis, "utf-8");
br = new BufferedReader(isr); dirFile = new File("d:" + File.separator + "gc3" + File.separator + fileName);
fw = new FileWriter(dirFile);
bw = new BufferedWriter(fw); String data = "";
bw.write("+++++++++++++" + Thread.currentThread().getName() + " 线程开始写文件++++++++++++");
while ((data = br.readLine()) != null) {
bw.write(data + "\r");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
} }

说明:

1、其实构思很简单,阻塞队列是线程安全的,那么我多线程就用阻塞队列,这样可以保证每个写线程拿到的具体内容不同,不会导致重复写数据;

2、我使用异步线程进行读写,而非同步线程,这样有助于提升整体读、写性能。

3、CountDownLatch是信号灯,功能类似于join()方法,当然也可以使用CyclicBarrier

java多线程批量读取文件( 八)--读写分离的更多相关文章

  1. java多线程批量读取文件(七)

    新公司入职一个多月了,至今没有事情可以做,十来个新同事都一样抓狂,所以大家都自己学习一些新东西,我最近在看zookeeper,感觉蛮不错的,和微服务的zuul以及eureka功能类似,只是代码复杂了一 ...

  2. java多线程批量下载文件

    多线程下载文件 平时开发中有时会用到文件下载,为了提高文件的下载速率,采用多线程下载能够达到事半功倍的效果: package test; /** * 文件下载类 * @author luweichen ...

  3. JAVA多线程下载网络文件

    JAVA多线程下载网络文件,开启多个线程,同时下载网络文件.   源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...

  4. R8—批量生成文件夹,批量读取文件夹名称+R文件管理系统操作函数

    一. 批量生成文件夹,批量读取文件夹名称 今日,工作中遇到这样一个问题:boss给我们提供了200多家公司的ID代码(如6007.7920等),需要根据这些ID号去搜索下载新闻,从而将下载到的新闻存到 ...

  5. 使用Perl批量读取文件最后行

    使用Perl批量读取文件最后行 面对成百上千个文件,有时我们需要查看它的最后行,单个文件打开将耗费大量时间,而通过Perl提取出最后行,将快速的帮助我们处理繁琐的事务. 特性 整个目录完全遍历,自动提 ...

  6. matlab文件读写处理实例(二)——textread批量读取文件

    问题:对文件夹下所有文件进行批量读取,跳过文件头部分,读取每个文件数据部分的7,8,9列,保存到变量并且输出到文件. 数据: 文件夹11m\

  7. Java io实现读取文件特殊内容进行替换

    最近公司在做一个项目其中一个需求是读取文件中的特殊字符在其后进行添加或删除字符操作,本来想直接使用randomAccessFile按行读取,读取到特殊字符就进行添加或删除操作,但是randomAcce ...

  8. [JAVA 多种方式读取文件]

    package com.file; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream ...

  9. Java相对路径读取文件

    不管你是新手还是老鸟,在程序中读取资源文件总会遇到一些找不到文件的问题,这与Java底层的实现有关,不能算bug,只要方法得当,问题还是可以解决的. 项目的文件夹结构: repathtest ├─sr ...

随机推荐

  1. intellijidea课程 intellijidea神器使用技巧 5-2 localhistory

    Ctrl shift A  ==>localhistory ==> show history 查看文件本地历史记录(idea每次修改在本地会生成历史记录) Ctrl shift A  == ...

  2. 升级jdk注意事项

    最好使用和编译的jdk相同版本的jre去执行.class程序. 今天在本地模拟部署项目到tomcat6就遇到了个坑. 我们项目使用的jdk1.7开发的,编译打war包放到webapps后,启动报错Ex ...

  3. Linux CentOS下部署Java Web项目

    本文讲解如何在Linux CentOS下部署Java Web项目的步骤. 一.环境准备: (1)Linux CentOS (2)apache-tomcat-9.0.10 (3)XShell 二.启动t ...

  4. Python输入与循环

    python while循环 while 语句: 执行语句 结束条件 #应用while输出1到11 counts = 1 while True: print("counts:", ...

  5. 网页打开速度优化——HTTP请求头及响应头

    no-cache:不缓存过期的资源 no-store:不缓存 最近看了<图解HTTP>这本书,书上讲到了这两者的区别: no-cache从字面意义上很容易误解为不缓存,但是no-cache ...

  6. graphql 项目搭建(二)

    一.Express基本框架 1.新建一个文件夹gql-server vscode 打开项目,在终端下输入yarn init -y 生成package.json 包(如果没安装yarn ,npm也一样, ...

  7. windows如何关闭指定端口

    关闭windows中被占用的端口,比如我们常见的8080端口被占用了 1.查找端口的PID netstat -aon|findstr "8080" 如图 PID为3888 2.关闭 ...

  8. Mysql limit 优化,百万至千万级快速分页,--复合索引的引用并应用于轻量级框架

    MySql 性能到底能有多高?用了php半年多,真正如此深入的去思考这个问题还是从前天开始.有过痛苦有过绝望,到现在充满信心!MySql 这个数据库绝对是适合dba级的高手去玩的,一般做一点1万篇新闻 ...

  9. 【转】使用webmagic搭建一个简单的爬虫

    [转]使用webmagic搭建一个简单的爬虫 刚刚接触爬虫,听说webmagic很不错,于是就了解了一下. webmagic的是一个无须配置.便于二次开发的爬虫框架,它提供简单灵活的API,只需少量代 ...

  10. redux详解

    redux介绍 学习文档:英文文档,中文文档,Github redux是什么 redux是一个独立专门用于做状态管理的JS库(不是react插件库),它可以用在react, angular, vue等 ...