在这里Java的方法中有线程递归,不懂得用什么方法求运行时间遇到一个有趣的问题,多线程扫描文件夹求运行时间。一般这种扫描文件夹耗时好像都是用的递归遍历一下进行计时,头一次看到这种一个文件夹一个线程的,这里按照原问题楼主的想法试着解决一下。

刚开始我是采用静态变量,共享总耗时,把每个run方法耗时都加上。

package com.brewin.codetuning.test;

import java.io.File;

import java.text.SimpleDateFormat;

import java.util.Date;

public class ThreadDemo02

{

public static void main(String args[]) {

File file=new File("D:\\AA");

MyThread mt1 = new MyThread("线程1",file);

mt1.start();

}

}

class MyThread extends Thread

{

private String name;

private File file;

public static int sum;

static {

sum = 0;

}

public MyThread(String name,File file) {

this.name = name;

this.file=file;

}

@Override

public void run() {

long startTime = System.currentTimeMillis();

File[] files=file.listFiles();

if(files!=null &&files.length>0) {

for(File f:files) {

if(f.isDirectory()) {

new MyThread(f.getName(),f).start();

}

// 打印文件名不方便看最后的耗时打印,注释掉

// else {

// System.out.println(Thread.currentThread().getName()+":"+f);

// }

}

}

// try {

// Thread.sleep(5000);

// }

// catch (InterruptedException e) {

// // TODO Auto-generated catch block

// e.printStackTrace();

// }

long endTime = System.currentTimeMillis();

long usedTime = (endTime-startTime);

sum+=usedTime;

System.out.println(name + " 运行结束,耗时: "+usedTime+" ms,sum现为:" +MyThread.sum+" ms");

}

}

控制台打印的什么呢?下面截取最后一部分

storage 运行结束,耗时: 0 ms,sum现为:3156 ms

x509 运行结束,耗时: 1 ms,sum现为:3157 ms

implementations 运行结束,耗时: 1 ms,sum现为:3158 ms

implementations 运行结束,耗时: 1 ms,sum现为:3159 ms

但是实际并没有用到3秒多,很快就结束了。

下面是加了Thread.sleep(5000)的结果,更明显一些:

xs 运行结束,耗时: 5004 ms,sum现为:2611580 ms

implementations 运行结束,耗时: 5001 ms,sum现为:2606576 ms

traversers 运行结束,耗时: 5001 ms,sum现为:2616581 ms

多线程是并发执行,所以这个思路是错误的,不能计算他们的总和,而是要计算他们的最开始的时间和最后的时间。改变思路,在最开始时初始化一个开始时间,后面每次线程结束后都更新一下最后时间,求他们之间的差值就可以了。

package com.brewin.codetuning.test;

import java.io.File;

public class ThreadDemo02

{

public static void main(String args[]) {

File file=new File("D:\\AA");

MyThread mt1 = new MyThread("线程1",file);

mt1.start();

}

}

class MyThread extends Thread

{

private static long startTime;

private String name;

private File file;

static {

startTime = System.currentTimeMillis();

}

public MyThread(String name,File file) {

this.name = name;

this.file=file;

}

@Override

public void run() {

File[] files=file.listFiles();

if(files!=null &&files.length>0) {

for(File f:files) {

if(f.isDirectory()) {

new MyThread(f.getName(),f).start();

}

// 打印文件名不方便看最后的耗时打印,注释掉

// }else {

// System.out.println(Thread.currentThread().getName()+":"+f);

// }

}

}

long usedTime = System.currentTimeMillis()-startTime;

System.out.println(name + " 运行结束,已耗时: "+usedTime+" ms");

}

}

控制台最后一段打印如下:

io 运行结束,已耗时: 164 ms

proxy 运行结束,已耗时: 164 ms

dom 运行结束,已耗时: 164 ms

serialize 运行结束,已耗时: 165 ms

fsm 运行结束,已耗时: 165 ms

rmi 运行结束,已耗时: 166 ms

spi 运行结束,已耗时: 166 ms

tree 运行结束,已耗时: 166 ms

graph 运行结束,已耗时: 166 ms

util 运行结束,已耗时: 166 ms

utils 运行结束,已耗时: 167 ms

protocol 运行结束,已耗时: 167 ms

implementations 运行结束,已耗时: 167 ms

http 运行结束,已耗时: 167 ms

content 运行结束,已耗时: 167 ms

resolver 运行结束,已耗时: 167 ms

util 运行结束,已耗时: 168 ms

identity 运行结束,已耗时: 168 ms

keyvalues 运行结束,已耗时: 168 ms

x509 运行结束,已耗时: 169 ms

xs 运行结束,已耗时: 169 ms

serializer 运行结束,已耗时: 169 ms

util 运行结束,已耗时: 169 ms

xs 运行结束,已耗时: 169 ms

util 运行结束,已耗时: 169 ms

validation 运行结束,已耗时: 170 ms

undo 运行结束,已耗时: 170 ms

traversers 运行结束,已耗时: 170 ms

util 运行结束,已耗时: 170 ms

namingutil 运行结束,已耗时: 170 ms

exceptions 运行结束,已耗时: 170 ms

CORBA 运行结束,已耗时: 171 ms

xpath 运行结束,已耗时: 171 ms

transforms 运行结束,已耗时: 171 ms

utils 运行结束,已耗时: 171 ms

params 运行结束,已耗时: 171 ms

encryption 运行结束,已耗时: 171 ms

signature 运行结束,已耗时: 171 ms

output 运行结束,已耗时: 171 ms

implementations 运行结束,已耗时: 172 ms

closure 运行结束,已耗时: 172 ms

concurrent 运行结束,已耗时: 172 ms

orbutil 运行结束,已耗时: 172 ms

helper 运行结束,已耗时: 172 ms

keyresolver 运行结束,已耗时: 172 ms

storage 运行结束,已耗时: 172 ms

implementations 运行结束,已耗时: 173 ms

implementations 运行结束,已耗时: 173 ms

resolver 运行结束,已耗时: 173 ms

implementations 运行结束,已耗时: 173 ms

models 运行结束,已耗时: 174 ms

implementations 运行结束,已耗时: 174 ms

opti 运行结束,已耗时: 174 ms

text 运行结束,已耗时: 174 ms

rtf 运行结束,已耗时: 174 ms

utils 运行结束,已耗时: 175 ms

giopmsgheaders 运行结束,已耗时: 175 ms

reference 运行结束,已耗时: 175 ms

regex 运行结束,已耗时: 175 ms

threadpool 运行结束,已耗时: 175 ms

res 运行结束,已耗时: 176 ms

html 运行结束,已耗时: 177 ms

parser 运行结束,已耗时: 177 ms

看到原问题楼主有提到CountDownLatch ,找来文章看了一下,不是很适合这里,CountDownLatch计数器的初始大小要跟任务数的大小一致(跟线程数无关),每执行一次任务,计数器减一(countDown),await()方法会一直阻塞主线程,直到计数器的值减为0,才会释放锁,如此便可以达到确保所有任务都完成才继续下一步的效果。

但是本文场景是不断递归new出新线程,并且本文场景中要求任务数和线程数是相等的,无法确定任务数,就没办法初始化CountDownLatch 大小。

想要用CountDownLatch 的话只能加个统计方法,获得文件夹数量,如下:

package com.brewin.codetuning.test;

import java.io.File;

import java.util.concurrent.CountDownLatch;

public class ThreadDemo02

{

static int count;

static {

count = 0;

}

public static void main(String args[]) {

File file = new File("D:\\AA");

countNumberOfFolders(file);

long startTime = System.currentTimeMillis();

MyThread mt1 = new MyThread("线程1", file);

mt1.start();

try {

MyThread.latch.await();

}

catch (InterruptedException e) {

e.printStackTrace();

}

long usedTime = System.currentTimeMillis() - startTime;

System.out.println("耗时: " + usedTime + " ms");

}

/**

* 统计文件夹数量

* @param f

* @exception/throws [违例类型] [违例说明]

* @see [类、类#方法、类#成员]

*/

public static void countNumberOfFolders(File f) {

count++;

File[] files = f.listFiles();

if (files != null && files.length > 0) {

for (File file : files) {

if (file.isDirectory()) {

countNumberOfFolders(file);

}

}

}

}

}

class MyThread extends Thread

{

private String name;

private File file;

static CountDownLatch latch;

static {

latch = new CountDownLatch(ThreadDemo02.count);

}

public MyThread(String name, File file) {

this.name = name;

this.file = file;

}

@Override

public void run() {

File[] files = file.listFiles();

if (files != null && files.length > 0) {

for (File f : files) {

if (f.isDirectory()) {

new MyThread(f.getName(), f).start();

}

// 打印文件名不方便看最后的耗时打印,注释掉

// }else {

// System.out.println(Thread.currentThread().getName()+":"+f);

// }

}

}

System.out.println(name + " 运行结束");

latch.countDown();

}

}

结果如下:

http 运行结束

output 运行结束

dom 运行结束

compiler 运行结束

util 运行结束

耗时: 350 ms

可以看到确实是等到所有的线程执行结束后才进行的下一步。

如上 结题

本作品采用《CC 协议》,转载必须注明作者和本文链接

java 多线程 扫描,多线程扫描文件夹耗时方法分析相关推荐

  1. DaisyDisk怎样以管理员身份扫描磁盘或文件夹

    有时您可能无法检查某些文件夹,因为您没有足够的访问权限.例如,即使您以管理员身份登录Mac,通常也无法访问某些系统文件夹和其他本地用户的文件夹.那么,使用DaisyDisk,怎样以管理员身份扫描磁盘或 ...

  2. 惠普打印机如何设置扫描到计算机,hp m435nw打印机怎么设置扫描到网络文件夹?...

    HP LaserJet Pro MFP M435nw 设置扫描到网络文件夹 1.以win7系统为例,点击计算机,双击c盘,新建文件夹命名435,在文件夹上点击右键选择属性,选择共享 2.点击高级共享, ...

  3. 理光复印机怎么扫描到文件夹服务器里,理光复印机扫描到文件夹设置方法.docx...

    理光复印机扫描到文件夹 的设置方法 -----------------注:此处以在桌面创建共享文件夹为示范-------------- 先在桌面创建一个文件夹,命名为"扫描文件" ...

  4. 扫描文件怎么设置到服务器,设置扫描到网络文件夹-HP.PDF

    设置扫描到网络文件夹-HP Color LaserJet Pro MFP M277 用户指南 /support/colorljMFPM277 HP Color LaserJet Pro MFP M27 ...

  5. HP CM6030/6040打印机怎么扫描到网络文件夹?

    HP Color LaserJet CM6030CM6040 MFP series如何设置扫描到网络文件夹 1.查找产品 IP 地址或主机名.在产品控制面板的主屏幕中,轻触网络地址按钮显示地址.打开 ...

  6. win10安全中心设置不扫描某个文件夹的方法

    使用win10系统怎么设置安全中心"windows defender"不扫描某个文件夹呢?这样自己想要保留的某些文件就不会因为这个原因被误删啦,下面我就来给大家讲一下怎么操作! 深 ...

  7. linux java读取文件夹下文件名,Java获取Linux上指定文件夹下所有第一级子文件夹...

    说明:需要只获得第一级文件夹目录 package com.sunsheen.jfids.studio.monitor.utils; import java.io.BufferedReader; imp ...

  8. java怎么获取服务器文件夹,java获取远程服务器的文件夹

    java获取远程服务器的文件夹 内容精选 换一换 工具中所有涉及上传文件功能的,如果需要上传的文件大于1GB或者解压后超过剩余磁盘空间的一半,则需要释放磁盘空间或手动将文件上传至服务器,其他情况可通过 ...

  9. java 创建文件夹的方法_Java创建文件夹的方法

    Java创建文件夹的方法 /** * 用于创建文件夹的方法 * @param mkdirName */ public void mkdir(String mkdirName) { try { File ...

最新文章

  1. linux删除zlib无法远程,linux zlib默认装在哪里
  2. 诗歌rails之如何写一个简单的Rails Plugin
  3. poj1273(最大网络流问题模版)
  4. 什么是CMU Pronoucing Dictionary(CMU发音词典)
  5. iOS10 UI教程基改变视图的外观与视图的可见性
  6. 乌当区利用大数据织密环境监测保护网
  7. 微信公众号关注用户的信息拉取
  8. anaconda成功安装fasttext后,无法导入的情况
  9. leetcode python3 简单题110. Balanced Binary Tree
  10. MTK:内存管理机制简单分析
  11. 编译使用CEF2623遇到的错误解决办法
  12. 【元胞自动机】基于matlab元胞自动机单车道交通流(时空图)【含Matlab源码 1681期】
  13. 实现离线地图行政区域划分
  14. 台式电脑投影切屏快捷键_电脑投影切屏快捷键
  15. android 平板原笔迹,iPad劲敌八:原笔迹输入你行吗?
  16. iOS 上传App Store 报 ITMS-90096错误处理方法
  17. 北华大学计算机程序设计算法提高训练营个人赛(无L)
  18. PDF转WORD为什么这么难
  19. IOS相关培训机构课程内容汇总
  20. Windows Error Code

热门文章

  1. Nginx 是如何实现高并发?常见的优化手段有哪些?
  2. 一个基于 SpringBoot 开源的小说和漫画在线阅读网站,简洁大方、强烈推荐
  3. java web项目请求控制及简单漏洞防范
  4. Servlet学习笔记(四)之请求转发与重定向(RequestDispatcher与sendRedirect)
  5. APP移动测试用例总结
  6. Kubernetes 架构(上)- 每天5分钟玩转 Docker 容器技术(120)
  7. springmvc结合freemarker,非自定义标签
  8. 用jquery或js实现三个div自动循环轮播
  9. BSD socket编程学习
  10. 如何查询mysql中执行效率低的sql语句