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
最后祝你们早日發財多线程
源码地址测试