用多线程计算目录文件大小
calculating directory file size with multi-Thread
我想写一个多线程计算目录及其子目录大小的程序。
我这样写:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
public class Innerclass {
Semaphore semaphore = new Semaphore(1);
private List<String> availableConnections = new ArrayList();
public Innerclass(){
this.availableConnections.add("A");
}
public String acquireConnection() throws InterruptedException {
semaphore.acquire();
System.out.println("Acquiring connection " + Thread.currentThread().getName());
return availableConnections.remove(0);
}
static Long count = 0L;
static File file1 ;
public static void main(String[] args) {
System.out.println(countFilesInDirectory(new File("target directory address")));
}
public static Long countFilesInDirectory(File directory) {
Innerclass connection = new Innerclass();
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);
Task task1 = new Task();
//Long count = 0L;
for (File file : directory.listFiles()) {
if (file.isFile()) {
executor.execute(new Runnable() {
@Override
public void run() {
try {
String far = connection.acquireConnection();
count += printFileSizeNIO(String.valueOf(file));
connection.acquireConnection();
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println(printFileSizeNIO(String.valueOf(file)));
}
});
}
if (file.isDirectory()) {
count += countFilesInDirectory(file);
}
}
executor.shutdown();
//System.out.println(task1.getCount());
//return task1.getCount();
return count;
}
public static Long printFileSizeNIO(String fileName) {
Path path = Paths.get(fileName);
Long bytes = 0L;
try {
bytes = Files.size(path);
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
}
该程序给出的结果接近实际,但无法准确计算。你认为问题是什么?
在单线程下,这个程序可以正常工作!
从用户那里接收当前路径和分片数量并进行计算。你觉得除了线程池还有别的方法可以写这个程序吗。谢谢各位教授。
使用执行程序服务,您的主线程不会等待池中的线程完成。
看这里:
我已经稍微更新了你的代码。它总是会给出相同的答案。
public class TestSF
{
Semaphore semaphore = new Semaphore(1);
public void acquireConnection() throws InterruptedException
{
semaphore.acquire();
}
public void releaseConnection() throws InterruptedException
{
semaphore.release();
}
static AtomicLong count = new AtomicLong(0);
public static void main(String[] args)
{
long bytes = countFilesInDirectory(new File("C:\Users\ashish\Desktop\Loader"));
System.out.println(humanReadableByteCountBin(bytes));
}
public static Long countFilesInDirectory(File directory)
{
TestSF connection = new TestSF();
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);
for (File file : Objects.requireNonNull(directory.listFiles()))
{
executor.execute(() -> {
if (file.isFile())
{
try
{
connection.acquireConnection();
count.addAndGet(printFileSizeNIO(String.valueOf(file)));
connection.releaseConnection();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
if (file.isDirectory())
{
countFilesInDirectory(file);
}
});
}
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException ex) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
return count.get();
}
public static Long printFileSizeNIO(String fileName)
{
Path path = Paths.get(fileName);
long bytes = 0L;
try
{
bytes = Files.size(path);
}
catch (IOException e)
{
e.printStackTrace();
}
return bytes;
}
public static String humanReadableByteCountBin(long bytes)
{
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
if (absB < 1024) {
return bytes + " B";
}
long value = absB;
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10)
{
value >>= 10;
ci.next();
}
value *= Long.signum(bytes);
return String.format("%.1f %ciB", value / 1024.0, ci.current());
}
}
我想写一个多线程计算目录及其子目录大小的程序。 我这样写:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
public class Innerclass {
Semaphore semaphore = new Semaphore(1);
private List<String> availableConnections = new ArrayList();
public Innerclass(){
this.availableConnections.add("A");
}
public String acquireConnection() throws InterruptedException {
semaphore.acquire();
System.out.println("Acquiring connection " + Thread.currentThread().getName());
return availableConnections.remove(0);
}
static Long count = 0L;
static File file1 ;
public static void main(String[] args) {
System.out.println(countFilesInDirectory(new File("target directory address")));
}
public static Long countFilesInDirectory(File directory) {
Innerclass connection = new Innerclass();
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);
Task task1 = new Task();
//Long count = 0L;
for (File file : directory.listFiles()) {
if (file.isFile()) {
executor.execute(new Runnable() {
@Override
public void run() {
try {
String far = connection.acquireConnection();
count += printFileSizeNIO(String.valueOf(file));
connection.acquireConnection();
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println(printFileSizeNIO(String.valueOf(file)));
}
});
}
if (file.isDirectory()) {
count += countFilesInDirectory(file);
}
}
executor.shutdown();
//System.out.println(task1.getCount());
//return task1.getCount();
return count;
}
public static Long printFileSizeNIO(String fileName) {
Path path = Paths.get(fileName);
Long bytes = 0L;
try {
bytes = Files.size(path);
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
}
该程序给出的结果接近实际,但无法准确计算。你认为问题是什么? 在单线程下,这个程序可以正常工作! 从用户那里接收当前路径和分片数量并进行计算。你觉得除了线程池还有别的方法可以写这个程序吗。谢谢各位教授。
使用执行程序服务,您的主线程不会等待池中的线程完成。
看这里:
我已经稍微更新了你的代码。它总是会给出相同的答案。
public class TestSF
{
Semaphore semaphore = new Semaphore(1);
public void acquireConnection() throws InterruptedException
{
semaphore.acquire();
}
public void releaseConnection() throws InterruptedException
{
semaphore.release();
}
static AtomicLong count = new AtomicLong(0);
public static void main(String[] args)
{
long bytes = countFilesInDirectory(new File("C:\Users\ashish\Desktop\Loader"));
System.out.println(humanReadableByteCountBin(bytes));
}
public static Long countFilesInDirectory(File directory)
{
TestSF connection = new TestSF();
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(20);
for (File file : Objects.requireNonNull(directory.listFiles()))
{
executor.execute(() -> {
if (file.isFile())
{
try
{
connection.acquireConnection();
count.addAndGet(printFileSizeNIO(String.valueOf(file)));
connection.releaseConnection();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
if (file.isDirectory())
{
countFilesInDirectory(file);
}
});
}
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException ex) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
return count.get();
}
public static Long printFileSizeNIO(String fileName)
{
Path path = Paths.get(fileName);
long bytes = 0L;
try
{
bytes = Files.size(path);
}
catch (IOException e)
{
e.printStackTrace();
}
return bytes;
}
public static String humanReadableByteCountBin(long bytes)
{
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
if (absB < 1024) {
return bytes + " B";
}
long value = absB;
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10)
{
value >>= 10;
ci.next();
}
value *= Long.signum(bytes);
return String.format("%.1f %ciB", value / 1024.0, ci.current());
}
}