在Java并发编程方面,计算密集型与IO密集型是两个非常典型的例子,这次大象就来讲讲自己在这方面的内容,本篇比较基础,只适合刚入门的童鞋,请各种牛人不喜勿喷。
计算密集型 计算密集型,顾名思义就是应用需要非常多的CPU计算资源,在多核CPU时代,我们要让每一个CPU核心都参与计算,将CPU的性能充分利用起来,这样才算是没有浪费服务器配置,如果在非常好的服务器配置上还运行着单线程程序那将是多么重大的浪费。对于计算密集型的应用,完全是靠CPU的核数来工作,所以为了让它的优势完全发挥出来,避免过多的线程上下文切换,比较理想方案是: 线程数 = CPU核数+1 也可以设置成CPU核数*2,这还是要看JDK的使用版本,以及CPU配置(服务器的CPU有超线程)。对于JDK1.8来说,里面增加了一个并行计算,计算密集型的较理想线程数 = CPU内核线程数*2 计算文件夹大小算是一个比较典型的例子,代码很简单,我就不多解释了。import java.io.File;import java.util.ArrayList;import java.util.Collections;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;/** * 计算文件夹大小 * @author 菠萝大象 */public class FileSizeCalc { static class SubDirsAndSize { public final long size; public final List执行10次后结果如下:subDirs; public SubDirsAndSize(long size, List subDirs) { this.size = size; this.subDirs = Collections.unmodifiableList(subDirs); } } private SubDirsAndSize getSubDirsAndSize(File file) { long total = 0; List subDirs = new ArrayList (); if (file.isDirectory()) { File[] children = file.listFiles(); if (children != null) { for (File child : children) { if (child.isFile()) total += child.length(); else subDirs.add(child); } } } return new SubDirsAndSize(total, subDirs); } private long getFileSize(File file) throws Exception{ final int cpuCore = Runtime.getRuntime().availableProcessors(); final int poolSize = cpuCore+1; ExecutorService service = Executors.newFixedThreadPool(poolSize); long total = 0; List directories = new ArrayList (); directories.add(file); SubDirsAndSize subDirsAndSize = null; try{ while(!directories.isEmpty()){ List > partialResults= new ArrayList >(); for(final File directory : directories){ partialResults.add(service.submit(new Callable (){ @Override public SubDirsAndSize call() throws Exception { return getSubDirsAndSize(directory); } })); } directories.clear(); for(Future partialResultFuture : partialResults){ subDirsAndSize = partialResultFuture.get(100,TimeUnit.SECONDS); total += subDirsAndSize.size; directories.addAll(subDirsAndSize.subDirs); } } return total; } finally { service.shutdown(); } } public static void main(String[] args) throws Exception { for(int i=0;i<10;i++){ final long start = System.currentTimeMillis(); long total = new FileSizeCalc().getFileSize(new File("e:/m2")); final long end = System.currentTimeMillis(); System.out.format("文件夹大小: %dMB%n" , total/(1024*1024)); System.out.format("所用时间: %.3fs%n" , (end - start)/1.0e3); } }}
![](http://www.blogjava.net/images/blogjava_net/bolo/concurrency/file_size_1.jpg)