(i) Single-threaded recursive method
Copy Code code as follows:
Package com.taobao.test;
Import Java.io.File;
public class Totalfilesizesequential {
public static String FileName = "C:\\Documents and settings\\administrator\\ desktop \\monkeytalk";
Recursively calculate the size of a file
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);
}
}
(ii) using Executors.newfixedthreadpool and callable multithread implementations
Copy Code code as follows:
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 settings\\administrator\\ desktop \\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 to 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 (MB, 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);
}
}
(iii) Another implementation that uses Executors.newfixedthreadpool and callable multiple threads
Copy Code code as follows:
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 settings\\administrator\\ desktop \\monkeytalk";
Private Long Gettotalsizeoffilesindir (final Executorservice service,
Final file file) throws Interruptedexception, Executionexception,
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 (M, timeunit.seconds);
}
return total;
}
Private Long gettotalsizeoffile (final String fileName)
throws Interruptedexception, Executionexception, 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,
Executionexception, 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);
}
}
(iv) using Countdownlatch and Atomiclong to implement concurrent control under multithreading
Copy Code code as follows:
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 settings\\administrator\\ desktop \\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 (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);
}
}
(v) Use of blockingqueue and Atomiclong implementations
Copy Code code as follows:
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 settings\\administrator\\ desktop \\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 (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);
}
}
(vi) Use of JDK7 forkjoin to achieve
Copy Code code as follows:
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 settings\\administrator\\ desktop \\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 ("/home"));
Final Long end = System.nanotime ();
System.out.println ("Total Size:" + total);
System.out.println ("Time Taken:" + (End-start)/1.0e9);
}
}