標籤:
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並發編程初探