(一)单线程递归方式
复制代码 代码如下: package com.taobao.test;
import java.io.File;
public class TotalFileSizeSequential {
public static String fileName = "C:Documents and SettingsAdministrator桌面monkeytalk";
// 递归方式 计算文件的大小 private long getTotalSizeOfFilesInDir(final File file) { if (file.isFile()) return file.length(); final File[] children = file.listFiles(); long total = 0; if (children != null) for (final File child : children) total += getTotalSizeOfFilesInDir(child); return total; }
public static void main(final String[] args) { final long start = System.nanoTime();
final long total = new TotalFileSizeSequential() .getTotalSizeOfFilesInDir(new File(fileName)); final long end = System.nanoTime(); System.out.println("Total Size: " + total); System.out.println("Time taken: " + (end - start) / 1.0e9); } }
(二)使用Executors.newFixedThreadPool和callable 多线程实现
复制代码 代码如下: package com.taobao.test;
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.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException;
public class ConcurrentTotalFileSize {
public static final String fileName = "C:Documents and SettingsAdministrator桌面monkeytalk";
class SubDirectoriesAndSize {
final public long size; final public List<File> subDirectories;
public SubDirectoriesAndSize(final long totalSize, final List<File> theSubDirs) { size = totalSize; subDirectories = Collections.unmodifiableList(theSubDirs); } }
private SubDirectoriesAndSize getTotalAndSubDirs(final File file) { long total = 0; final List<File> subDirectories = new ArrayList<File>(); if (file.isDirectory()) { final File[] children = file.listFiles(); if (children != null) for (final File child : children) { if (child.isFile()) total += child.length(); else subDirectories.add(child); } } return new SubDirectoriesAndSize(total,subDirectories); }
private long getTotalSizeOfFilesInDir(final File file) throws InterruptedException,ExecutionException,TimeoutException { final ExecutorService service = Executors.newFixedThreadPool(100); try { long total = 0; final List<File> directories = new ArrayList<File>(); directories.add(file); while (!directories.isEmpty()) { final List<Future<SubDirectoriesAndSize>> partialResults = new ArrayList<Future<SubDirectoriesAndSize>>(); for (final File directory : directories) { partialResults.add(service .submit(new Callable<SubDirectoriesAndSize>() { public SubDirectoriesAndSize call() { return getTotalAndSubDirs(directory); } })); } directories.clear(); for (final Future<SubDirectoriesAndSize> partialResultFuture : partialResults) { final SubDirectoriesAndSize subDirectoriesAndSize = partialResultFuture .get(100,TimeUnit.SECONDS); directories.addAll(subDirectoriesAndSize.subDirectories); total += subDirectoriesAndSize.size; } } return total; } finally { service.shutdown(); } }
public static void main(final String[] args) throws InterruptedException, ExecutionException,TimeoutException { final long start = System.nanoTime(); final long total = new ConcurrentTotalFileSize() .getTotalSizeOfFilesInDir(new File(fileName)); final long end = System.nanoTime(); System.out.println("Total Size: " + total); System.out.println("Time taken: " + (end - start) / 1.0e9); } }
(三)使用Executors.newFixedThreadPool和callable 多线程的另外一种实现
复制代码 代码如下: package com.taobao.test;
import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException;
public class NaivelyConcurrentTotalFileSize { public static String fileName = "C:Documents and SettingsAdministrator桌面monkeytalk";
private long getTotalSizeOfFilesInDir(final ExecutorService service, final File file) throws InterruptedException, TimeoutException { if (file.isFile()) return file.length();
long total = 0; final File[] children = file.listFiles();
if (children != null) { final List<Future<Long>> partialTotalFutures = new ArrayList<Future<Long>>(); for (final File child : children) { partialTotalFutures.add(service.submit(new Callable<Long>() { public Long call() throws InterruptedException, ExecutionException,TimeoutException { return getTotalSizeOfFilesInDir(service,child); } })); }
for (final Future<Long> partialTotalFuture : partialTotalFutures) total += partialTotalFuture.get(100,TimeUnit.SECONDS);
}
return total;
}
private long getTotalSizeOfFile(final String fileName) throws InterruptedException,TimeoutException { final ExecutorService service = Executors.newFixedThreadPool(100); try { return getTotalSizeOfFilesInDir(service,new File(fileName)); } finally { service.shutdown(); } }
public static void main(final String[] args) throws InterruptedException,TimeoutException { final long start = System.nanoTime(); final long total = new NaivelyConcurrentTotalFileSize() .getTotalSizeOfFile(fileName); final long end = System.nanoTime(); System.out.println("Total Size: " + total); System.out.println("Time taken: " + (end - start) / 1.0e9); } }
(四)使用CountDownLatch和AtomicLong实现多线程下的并发控制
复制代码 代码如下: package com.taobao.test;
import java.io.File; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong;
public class ConcurrentTotalFileSizeWLatch { private ExecutorService service; final private AtomicLong pendingFileVisits = new AtomicLong(); final private AtomicLong totalSize = new AtomicLong(); final private CountDownLatch latch = new CountDownLatch(1); public static String fileName = "C:Documents and SettingsAdministrator桌面monkeytalk";
private void updateTotalSizeOfFilesInDir(final File file) { long fileSize = 0; if (file.isFile()) fileSize = file.length(); else { final File[] children = file.listFiles(); if (children != null) { for (final File child : children) { if (child.isFile()) fileSize += child.length(); else { pendingFileVisits.incrementAndGet(); service.execute(new Runnable() { public void run() { updateTotalSizeOfFilesInDir(child); } }); } } } } totalSize.addAndGet(fileSize); if (pendingFileVisits.decrementAndGet() == 0) latch.countDown(); }
private long getTotalSizeOfFile(final String fileName) throws InterruptedException { service = Executors.newFixedThreadPool(100); pendingFileVisits.incrementAndGet(); try { updateTotalSizeOfFilesInDir(new File(fileName)); latch.await(100,TimeUnit.SECONDS); return totalSize.longValue(); } finally { service.shutdown(); } }
public static void main(final String[] args) throws InterruptedException { final long start = System.nanoTime(); final long total = new ConcurrentTotalFileSizeWLatch() .getTotalSizeOfFile(fileName); final long end = System.nanoTime(); System.out.println("Total Size: " + total); System.out.println("Time taken: " + (end - start) / 1.0e9); } }
(五)使用BlockingQueue和AtomicLong的实现
复制代码 代码如下: package com.taobao.test;
import java.io.File; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong;
public class ConcurrentTotalFileSizeWQueue { public static String fileName = "C:Documents and SettingsAdministrator桌面monkeytalk";
private ExecutorService service; final private BlockingQueue<Long> fileSizes = new ArrayBlockingQueue<Long>( 500); final AtomicLong pendingFileVisits = new AtomicLong();
private void startExploreDir(final File file) { pendingFileVisits.incrementAndGet(); service.execute(new Runnable() { public void run() { exploreDir(file); } }); }
private void exploreDir(final File file) { long fileSize = 0; if (file.isFile()) fileSize = file.length(); else { final File[] children = file.listFiles(); if (children != null) for (final File child : children) { if (child.isFile()) fileSize += child.length(); else { startExploreDir(child); } } } try { fileSizes.put(fileSize); } catch (Exception ex) { throw new RuntimeException(ex); } pendingFileVisits.decrementAndGet(); }
private long getTotalSizeOfFile(final String fileName) throws InterruptedException { service = Executors.newFixedThreadPool(100); try { startExploreDir(new File(fileName)); long totalSize = 0; while (pendingFileVisits.get() > 0 || fileSizes.size() > 0) { final Long size = fileSizes.poll(10,TimeUnit.SECONDS); totalSize += size; } return totalSize; } finally { service.shutdown(); } }
public static void main(final String[] args) throws InterruptedException { final long start = System.nanoTime(); final long total = new ConcurrentTotalFileSizeWQueue() .getTotalSizeOfFile(fileName); final long end = System.nanoTime(); System.out.println("Total Size: " + total); System.out.println("Time taken: " + (end - start) / 1.0e9); } }
(六)使用jdk7的ForkJoin来实现
复制代码 代码如下: package com.taobao.test;
import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveTask;
public class FileSize { private final static ForkJoinPool forkJoinPool = new ForkJoinPool(); public static String fileName = "C:Documents and SettingsAdministrator桌面monkeytalk";
private static class FileSizeFinder extends RecursiveTask<Long> { final File file;
public FileSizeFinder(final File theFile) { file = theFile; }
@Override public Long compute() { long size = 0; if (file.isFile()) { size = file.length(); } else { final File[] children = file.listFiles(); if (children != null) { List<ForkJoinTask<Long>> tasks = new ArrayList<ForkJoinTask<Long>>(); for (final File child : children) { if (child.isFile()) { size += child.length(); } else { tasks.add(new FileSizeFinder(child)); } } for (final ForkJoinTask<Long> task : invokeAll(tasks)) { size += task.join(); } } } return size; } }
public static void main(final String[] args) { final long start = System.nanoTime(); final long total = forkJoinPool.invoke(new FileSizeFinder(new File("/home"))); final long end = System.nanoTime(); System.out.println("Total Size: " + total); System.out.println("Time taken: " + (end - start) / 1.0e9); } }
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|