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();
线程池的大小并不是设置的越大越好,根据具体的环境而来,
时间: 2024-10-11 17:35:47