Callable是相似Runnable的類,主要區別在於Callable是能夠返回結果,而Runnable不會。java
簡單說FutureTask的做用是能夠啓用、取消、而且判斷線程是否完成,能夠搭配Callable和Runnable使用。和Callable一塊兒使用時,能夠實如今線程完成任務後獲取返回結果。git
衆所周知,爲何要使用多線程,無非是爲了加快任務的處理速度。好比如今須要你計算某個目錄下的文件數量,你能夠選擇單線程遍歷統計,也能夠考慮使用多線程遍歷查詢。github
public class FileCountCallableTest { public static void main(String[] args){ //填寫你想統計的文件夾目錄 File root = new File("D:\\"); countByConcurrent(root); countBySingle(root); } /** * 多線程計算文件數量 * * 獲取目標目錄下的子目錄,並把每一個子目錄生成新線程任務達到加快計算目的 * * @param targetDir */ static void countByConcurrent(File targetDir){ try { long t1 = System.currentTimeMillis(); File[] files = targetDir.listFiles(); ExecutorService es = Executors.newFixedThreadPool(4); List<FutureTask> futureTaskList = new ArrayList<FutureTask>(); int sumCount = 0; for(File file:files){ if(file.isDirectory()){ //每一個目錄生成新線程任務 FileCountCallable fileCountCallable = new FileCountCallable(file.getPath()); FutureTask<Integer> futureTask = new FutureTask(fileCountCallable); es.submit(futureTask); futureTaskList.add(futureTask); }else{ sumCount++; } } //把每一個任務的計算結果相加,得出最終結果 for(FutureTask<Integer> futureTask:futureTaskList){ sumCount += futureTask.get(); } es.shutdown(); System.out.println("sumCount:"+sumCount); System.out.println("countByConcurrent finish takes:"+(System.currentTimeMillis() - t1)); }catch (Exception e){ e.printStackTrace(); } } /** * 單線程計算文件數量 * * @param targetDir */ static void countBySingle(File targetDir){ try { long t1 = System.currentTimeMillis(); int sumCount = FileHelper.searchFiles(targetDir); System.out.println("sumCount:"+sumCount); System.out.println("countBySingle finish takes:"+(System.currentTimeMillis() - t1)); }catch (Exception e){ e.printStackTrace(); } } }
public class FileCountCallable implements Callable<Integer>{ private File root; public Integer call() { long t1 = System.currentTimeMillis(); int count = FileHelper.searchFiles(root); return count; } public FileCountCallable(String pathName) { root = new File(pathName); } }
代碼比較簡單,好比一個目錄下有x、y、z三個文件夾,我能夠一個線程去遍歷計算,也能夠啓用3個線程分別去計算,最終把3個線程的結果相加就是最終結果。
最終我在本機上測試的結果:sql
sumCount:155963 countByConcurrent finish takes:7793 ms sumCount:155963 countBySingle finish takes:9608 ms
採用多線程任務的方式,節省了18.9%的時間,相差並非很大,主要是由於個人文件分佈不均勻,採起以上策略時有的任務工做量大、有的很小,若是是分佈比較均勻的話節省時間能夠達到50%。固然要根據實際的需求調整多任務的策略,儘可能使每一個任務的工做量相差並不大。數據庫
還有在咱們實際項目中可使用的場景:api
最後祝你們早日發財多線程
源碼地址測試