能不能帮我分析下这两个程序的效率问题

fairjm 2012-07-15 01:49:59
想用用多线程
然后做了程序1 发现设计有点问题 阻塞在for循环了 这样就和不用多线程一样的效果
后来又改了2 把阻塞从for里拿出来 那样就可以形成多个线程去计数当前文件夹下的文件(当然要当前文件夹下的所有文件计数完毕才会返回上一级 程序一也一样...)
运行了下...发现时间消耗居然差不多 都在14s左右 就差个几十毫秒的样子.................
求解..
import java.io.File;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;


public class ListFileWithFutureTask {
public static void main(String[] args) throws Exception {
FutureTask<Integer> f=new FutureTask<Integer>(new Callable<Integer>(){
public Integer call(){
return search(new File("c:\\"));
}
});
Date begin=new Date();
f.run();
System.out.println(f.get());
Date end=new Date();
System.out.println(begin.getTime()-end.getTime());

}

public static int search(File s){ //以下虽然产生了线程 但是效率还是一样低得可怕(线程等待...其实最多也就产生了一个 大错误....)
final File[] ss=s.listFiles();
int count=0;
if(ss!=null){
for(int i=0;i<ss.length;i++){
if(ss[i].isDirectory()){
final File sss=ss[i]; //若是目录 则建新线程开始计数
FutureTask<Integer> f=new FutureTask<Integer>(new Callable<Integer>(){
public Integer call(){
return search(sss);
}
});
f.run(); //这边会产生递归调用 但和单线程不同 这边的递归调用是多线的
try {
count+=f.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}else{
count++; //不是文件就计数
}
}
}
return count;

}
}


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.io.File;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;


public class ListFileWithFutureTask2 {
public static void main(String[] args) throws Exception {
FutureTask<Integer> f=new FutureTask<Integer>(new Callable<Integer>(){
public Integer call(){
return search(new File("c:\\"));
}
});
Date begin=new Date();
f.run();
System.out.println(f.get());
Date end=new Date();
System.out.println(begin.getTime()-end.getTime());

}

public static int search(File s){
final File[] ss=s.listFiles();
List<FutureTask<Integer>> fl=new ArrayList<FutureTask<Integer>>();
int count=0;
if(ss!=null){
for(int i=0;i<ss.length;i++){
if(ss[i].isDirectory()){
final File sss=ss[i]; //若是目录 则建新线程开始计数
FutureTask<Integer> f=new FutureTask<Integer>(new Callable<Integer>(){
public Integer call(){
return search(sss);
}
});
f.run();
fl.add(f);
}else{
count++;
}
}
for(FutureTask<Integer> i:fl){
try {
count=count+i.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return count;

}
}


不要担心可见性及其他问题 因为我里面没有用到域 全是局部变量 不会有太大的问题(虽然计数的准确性无法考证...两次计数我的c盘 在9w6左右 有个别数偏差)
...全文
121 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
fairjm 2012-07-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

两端代码确实差别不是太大
程序1是堵在for里,程序2是堵在第二个for里
从多线程的角度来考虑,程序2更体现出多线程,因为程序1真的就相当于单线程了

LZ要清楚,多线程的目的不是为了提高效率,是为了协调线程的并发协作,因为对CPU来说,多线程是频繁切换CPU去执行,这样程序不会因为堵塞在某个处理而造成后续的处理等待,但是如果后续的处理依赖于前面多线程的结果,那么CPU频繁的切换还不如……
[/Quote]
恩 恩 多谢解答 不过对于相同的一系列操作 用多线程去划分任务然后完成效率应该比用单线会提高一点把o(∩∩)o
qybao 2012-07-15
  • 打赏
  • 举报
回复
两端代码确实差别不是太大
程序1是堵在for里,程序2是堵在第二个for里
从多线程的角度来考虑,程序2更体现出多线程,因为程序1真的就相当于单线程了

LZ要清楚,多线程的目的不是为了提高效率,是为了协调线程的并发协作,因为对CPU来说,多线程是频繁切换CPU去执行,这样程序不会因为堵塞在某个处理而造成后续的处理等待,但是如果后续的处理依赖于前面多线程的结果,那么CPU频繁的切换还不如单线程效率高.

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧