文件目录遍历的并发算法
问题:算出指定目录下文件的大小.
这个是个很简单的问题嘛,直接做个递归就行,上顺序算法:
public long getFileSize(final File file){if(file.isFile()){return file.length();}else{long total = 0;File files[] = file.listFiles();if(files == null)return 0;for(File f: files){total += getFileSize(f);}return total;}}
很简单,一个递归实现,那么现在我们思考并发的算法
并发思路:每次进行递归运算,每次开一个线程去计算当前目录的文件大小,然后进行递归运算
并发代码:
private long getFileSizebf(final ExecutorService service,final File file) throws InterruptedException, ExecutionException, TimeoutException{if(file.isFile())return file.length();else{final File files[] = file.listFiles();if(files == null)return 0;else{long total = 0;final List<Future<Long>> tasks = new ArrayList<Future<Long>>();for(final File f : files){tasks.add(service.submit(new Callable<Long>() {@Overridepublic Long call() throws Exception {// TODO Auto-generated method stub //进行递归,把子目录的文件大小返回return getFileSizebf(service, f);}}));}for(final Future<Long> fl : tasks){total += fl.get();}return total;}}}
看上去没什么问题,我们来实际测试下;
我们看到,调用get从Future中取数据的时候,并没有设置超时,实际运行中发现,当文件夹的目录结构简单,目录树比较浅的时候能够跑出来,但是目录树结构复杂了以后,跑了很久还是跑不出来结果.
分析:我们每个线程会开启新的线程去计算子目录的大小,这个时候,线程会进入等待,等待子线程的返回结果,这个时候就会出现一种情况,假如目录树的结构复杂,那么很多线程会进入等待状态,等待子线程的返回值,但是这些父线程还是占用着线程池,但是子线程请求不到线程池去执行,这个时候就会进入死锁.
如下图:
优化策略:1.既然是线程池的poolsize不够用了,那么我们就增加poolsize的大小嘛,好了,现在我们面对的是一个目录结构不那么复杂的,通过简单地增加poolsize还可以做到,但是非常复杂的话就没办法了.
2.我们之所以会造成死锁,是因为线程在占用线程池的情况下同时在等待子线程的返回结果,
优化版本1:
public class FileOPBX1 implements FileOpI {@Overridepublic long getTotalSizeOfFilesInDir(File f) {long total = 0;final ExecutorService eService = Executors.newFixedThreadPool(100);// TODO Auto-generated method stubfinal List<File> dirs = new ArrayList<>();dirs.add(f);//初始化当前文件夹while (!dirs.isEmpty()) {//每次计算dir里面一集目录下的文件大小以及子目录final List<Future<SubDirAndSize>> part = new ArrayList<>();for (final File dir : dirs) {part.add(eService.submit(new Callable<SubDirAndSize>() {@Overridepublic SubDirAndSize call() throws Exception {// TODO Auto-generated method stubreturn getEveryDir(dir);}}));}dirs.clear();//目录分配任务完毕,清除//从返回的结果计算文件大小,并且把新的子目录添加到待计算文件夹for (final Future<SubDirAndSize> subdir : part) {try {final SubDirAndSize sas = subdir.get();total += sas.size;dirs.addAll(sas.subDirs);} catch (InterruptedException | ExecutionException e) {// TODO Auto-generated catch block e.printStackTrace();}}System.out.println(dirs);}return total;}//计算当前一级目录下文件的大小以及子目录private SubDirAndSize getEveryDir(final File f) {long total = 0;final List<File> subDirs = new LinkedList<File>();if (f.isDirectory()) {final File[] sub = f.listFiles();if (sub != null) {for (final File dir : sub) {if (dir.isFile())total += dir.length();else {subDirs.add(dir);}}}}return new SubDirAndSize(total, subDirs);}public class SubDirAndSize {final public long size;final public List<File> subDirs;public SubDirAndSize(final long totalsize, final List<File> thesubDir) {size = totalsize;subDirs = Collections.unmodifiableList(thesubDir);}}}
这个时候我们看结果:
运行花费时间9688
串行执行结果:19563974028
运行花费时间3230
并行执行结果:19563974028
转载于:https://www.cnblogs.com/color-my-life/p/4352551.html
文件目录遍历的并发算法相关推荐
- 非递归遍历二叉树(算法导论第三版第十章10.4-5)
非递归遍历二叉树(算法导论第三版第十章10.4-5) template<typename T> void TraverseBinaryTreeNonRecursive(BinaryTree ...
- Android安全开发之ZIP文件目录遍历
1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在"../"的字符串,攻击者可以利用多个"../"在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原 ...
- 二叉树广度和深度遍历的全部算法
二叉树广度和深度遍历的全部算法 对于二叉树的遍历,有广度遍历和深度遍历两大类,对于深度遍历又分为先序.中序和后序,这三种先中后序又可以用递归和非递归两种算法来写,下面就分别对这两大类算法做个总结,以后 ...
- 北邮22信通:二叉树各种遍历所有常见算法汇总
北邮22信通一枚~ 跟随课程进度每周更新数据结构与算法的代码和文章 持续关注作者 解锁更多邮苑信通专属代码~ 获取更多文章 请访问专栏~ 北邮22信通_青山如墨雨如画的博客-CSDN博客 ...
- [免费专栏] Android安全之ZIP文件目录遍历漏洞
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬请移步知 ...
- 使用计算机频繁使用的算法,基于DHP的频繁遍历路径挖掘算法-天津大学计算机学院.PDF...
基于DHP的频繁遍历路径挖掘算法-天津大学计算机学院 维普资讯 第25卷第 5期 杭 州 电子 科 技 大 学 学报 Vo1.25.No.5 2005年 10月 Jounud of I-la~ hou ...
- c语言 迷宫深度遍历 算法,图的遍历迷宫生成算法浅析
1. 引言 在平常的游戏中,我们常常会碰到随机生成的地图.这里我们就来看看一个简单的随机迷宫是如何生成. 2. 迷宫描述随机生成一个m * n的迷宫,可用一个矩阵maze[m][n]来表示,如图: ...
- morris算法(莫里斯遍历) [数据结构与算法]
morris算法(莫里斯算法) Morris算法, 我们最常用于解决二叉树的遍历问题, 以及与遍历相关的一些问题(其实在二叉树系列问题中, 我们解决各种问题的时候都要涉及到一个对二叉树的遍历) 我们先 ...
- 树的前序、中序、后序遍历及深度优先算法DFS、广度优先算法BFS及python实现
刷Leetcode时遇到一种经典数据结构--树,树是典型递归思想来的,学习树有助于学习递归思想以及栈.队列(后续细说),本文对树的结构.遍历算法以及Python实现做总结,以供复习拓展 树是连通的无环 ...
最新文章
- Qt之QGraphicsView实战篇(很强大)
- Python-02-基础知识
- qos和被qos是什么意思
- 对字符串进行 匹配,查找,替换,判断。
- 操作数组的常用方式二-----排序、查找
- iOS-----线程同步与线程通信
- 2021年中国专业话筒市场趋势报告、技术动态创新及2027年市场预测
- java derby xsai2,java-j内的引用罐
- PHP数字格式化,每三位逗号分隔数字,可以保留小数
- 高通QCC3020应用开发的软件平台的搭建
- vrep与vs2015联合仿真(C/C++)
- Ansys-结构动力学分析-悬臂梁模态分析学习收获
- 陈玉琴老师的中医理学
- 自助装机配置专家点评3
- SNS背后的科:从六度分隔到无尺度网络,互联网营销
- mysql查询工龄在20年以上_数据库查询练习
- java游戏怎么导入jme3,java - JME:将带有纹理的Cinema 4d模型导入jMonkey Projekt - 堆栈内存溢出...
- lp_solve 线性规划求解包的使用
- 用html和css制作小黄人,CSS3 小黄人案例
- 输入一个整数x,判断其能否被3整除也被7整除。
热门文章
- [Oracle 学习] Oracle中将查询语句执行结果导入文本文件
- 我在学习技术的过程遇到的不会的单词(不断完善)
- VS.NET 2005真是太好用了!
- Openwrt配置ssh自动登录服务器socks5转发
- 从零开始学电脑_《新手从零开始学电脑》1.6——怎样才能打一手好字
- 设置计算机关机静音,Shortcuts 捷径控制 Windows 电脑:静音开关、音量调节、待机、关机...
- computed get set 传参_ES6 的 Set 与 Map深入理解
- P1216 [IOI1994][USACO1.5]数字三角形 Number Triangles(简单dp)
- hihocoder#1041 : 国庆出游(DFS)
- 因子和(类素数筛选法)