package test;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; public class Test {
public static void getJavaFile(String currentpath,List<File> files){
File dir = new File(currentpath);
if(dir.exists()){
File temp[] = dir.listFiles();
if(temp != null)
{
for (File b: temp) {
if (b.isFile() && b.toString().endsWith(".java")) {
files.add(b);
}
else if(b.isDirectory()){
getJavaFile(b.toString(), files);
}
}
}
}
}
public final static float percent = (float) 0.9;
public final static int poolsize = (int) (Runtime.getRuntime().availableProcessors()/(1-percent));
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//初始化文件集合
String path = "G:"+File.separator+"src";
List<File> fs = new ArrayList<>();
getJavaFile(path, fs); //顺序执行
long start = System.currentTimeMillis();
int total = 0;
for(File s : fs){
int i = getCount(s);
//System.out.println(s.getName()+"长度为:"+i);
total+=i;
}
long end = System.currentTimeMillis();
System.out.println("顺序执行的时间:"+(end-start)+"得出来的结果:"+total); final ExecutorService executorpool = Executors.newFixedThreadPool(poolsize);
final List<Callable<Integer>> partitions = new ArrayList<>();
for(final File f1 : fs){
partitions.add(new Callable<Integer>() { @Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
Integer i = getCount(f1);
//System.out.println(f1.getName()+"长度为:"+i);
return i;
}
});
}
long startbingfa = System.currentTimeMillis();
final List<Future<Integer>> nums = executorpool.invokeAll(partitions,5,TimeUnit.MINUTES);
int totalbingfa = 0;
for(final Future<Integer>i : nums){
totalbingfa = totalbingfa+i.get();
}
executorpool.shutdown();
long endbingfa = System.currentTimeMillis();
System.out.println("并发的时间:"+(endbingfa-startbingfa)+"得出来的结果:"+totalbingfa); } public static int getCount(File f) throws IOException{
int count = 0;
Reader br = new FileReader(f);
//String line = "";
int c;
while ((c = br.read()) != -1) {
if('a' == (char)c){
count++;
}
}
return count;
}
}

上面可以看到,我设置了大量的文件,然后使用并发和顺序执行,执行结果如下:

顺序执行的时间:140得出来的结果:14002
并发的时间:86得出来的结果:14002

可以看到,其实改进并不特别明显,究其原因就是,代码中的任务的IO密集型特征并不明显,但是就这个而言,时间仍然是有所改进的,采用的是线程池方式,首先定义一个任务集合partitions,

final List<Callable<Integer>> partitions = new ArrayList<>();

其中Integer表示的是任务的返回类型

然后给任务集定义任务,比如上面的就是一个读取文件并且返回一个Integer类型的数据.

然后定义任务服务

final ExecutorService executorpool =Executors.newFixedThreadPool(poolsize);

这里设置的是线程池的大小,也就是能够同时运行的任务数.

然后开始执行

final List<Future<Integer>> nums = executorpool.invokeAll(partitions,5,TimeUnit.MINUTES);

这里返回的是任务集合的全体的返回结果,然后我们遍历nums,用get方法去得到单个结果.

最后要关闭线程池

executorpool.shutdown();

线程池的大小并不是设置的越大越好,根据具体的环境而来,

Java并发编程初探的更多相关文章

  1. java并发编程资料

    并发这玩意很有用,把自己在网上看过觉得总结的很好的资料分享出来.猛击下面的地址查看吧 java并发编程:线程池的使用说明 java并发编程系列文章 Java并发性和多线程专题 并发工具类 Java 7 ...

  2. 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

    章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...

  3. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  4. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  5. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  6. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  7. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  8. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

  9. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

随机推荐

  1. MAT(Memory Analyzer Tool)工具入门介绍

    1.MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗 ...

  2. About_PHP

    所谓PHP: 超文本预处理器 外文名称 Hypertext Preprocessor 编程范型 面向对象.命令式编程 php就是比js更高端的一种语言. 语法有两种: <?php      ?& ...

  3. AJAX 后台返回多种数据

    前台ajax(jsp文件): (1) $.ajax({ type: "POST", url: "/dragable/demo/finishTopo", asyn ...

  4. maven pom文件结构详解

    POM文件结构 Project Object Model是Maven2项目的基础所在,简单来说它就是一个XML文件,Maven2用它来描述一个工程的整个生命周期所需要执行的一系列功能和特性. 最小配置 ...

  5. CKPT进程工作机制

    CKPT进程工作示意图 2.CKPT进程工作机制 检查点进程被触发的条件为: a> 当发生日志组切换时: b>  用户提交了事务时(commit): c>  Redo log buf ...

  6. ss命令

    看到好的博文,所以记录一下.本文出自转载. ss是Socket Statistics的缩写.顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它 ...

  7. C# 常用类

    一.Convert 主要用于数据类型的转换,常用的静态方法有: Convert.ToSingle():把数据转换为单精度浮点数,参数常为字符串 Convert.ToDouble():转为双精度浮点数 ...

  8. node js 模块分类

    核心模块 require('fs'); 核心模块是被编译成二进制代码 文件模块 require('../fs.js'); 对于加载模块时既没指出./ ../ /.../时,加载模块的搜索路径.如果'/ ...

  9. 全局方法&Number对象

    //js端 function println(string){ document.write(string+"<br/>"); } //html端 <script ...

  10. php Output Control 函数 ob_系列函数详解

    <?php /* * 输出缓冲控制 * * flush — 刷新输出缓冲 ob_clean — 清空(擦掉)输出缓冲区 ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲 ob_en ...