我正在为我的目的开发一个简单的搜索工具。 我的目的是搜索指定文件夹下的所有文件或特定文件。 我想过多线程。 每个线程将开始搜索文件,并将该文件放入该文件的列表中 列表中不包含。 因此每个线程都不会扫描同一个文件。
我不确定这是不是正确的做法。 当我运行程序时,当我使用一个线程,两个时,我可以看到相同的结果 甚至超过两个。
然后我使用了Executor服务,我仍然得到相同的执行时间。我不能 找到差异。我的问题如下。
1.我使用正确的逻辑来搜索多个线程的文件吗?
2.我可以在执行一个线程,两个线程等时获得差异吗?
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class FileReaderRunnable implements Runnable {
private List<File> fileList = new ArrayList<>();
private File mfile;
public boolean finished;
public FileReaderRunnable(File file) {
this.mfile = file;
}
@Override
public void run() {
//System.out.println("Thread current:"+Thread.currentThread().getName());
//while(!finished){
getfiles(mfile);
//finished = false;
//}
}
public void setFlag(boolean value) {
finished = value;
}
public void getfiles(File file) {
System.out.println("EXecuting...: "+Thread.currentThread().getName()+file.getAbsolutePath());
File[] listFiles = file.listFiles();
if (listFiles != null && listFiles.length > 0) {
for (File file2 : listFiles) {
if(!fileList.contains(file2.getAbsoluteFile())){
fileList.add(file2.getAbsoluteFile());
}
getfiles(file2);
}
}
}
public List<File> getFiles(){
return fileList ;
}
}
public class FileReaderThreadMain {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(30);
File file = new File("C:\\Temp");
FileReaderRunnable r = new FileReaderRunnable(file);
long startTime = System.nanoTime();
executor.execute(r);
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
long endTime = System.nanoTime();
System.out.println("\nFinished all threads");
System.out.println("main thread exited");
List<File> files = r.getFiles();
System.out.println("Total Files size: "+files.size());
long duration = (endTime - startTime);
System.out.println("Duration: "+duration/1000000 );
}
}
答案 0 :(得分:0)
你可以这样做:
public class Test {
private static final int THREAD_COUNT = 3;
private static int taskDoneCount=0;
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
List<String> allFiles = new ArrayList<>();
File dir = new File("C:\\Temp");
File[] files = dir.listFiles();
int length = files.length;
int onePart = length / THREAD_COUNT;
long startTime = System.currentTimeMillis();
for (int i = 0; i < THREAD_COUNT; i++) {
int startIndex = i * onePart; // the start index of the file list
int endIndex = onePart * (i + 1);// the end index of the file list
if (i == THREAD_COUNT-1) {
endIndex = files.length;
}
System.out.println("Thread#"+(i+1)+" start index:"+startIndex+", end index:"+(endIndex-1));
executor.execute(new SearchFileThread(startIndex, endIndex, files, fileList -> {
synchronized (Test.class) {
taskDoneCount++;
allFiles.addAll(fileList);
if (taskDoneCount == THREAD_COUNT) {// check if all tasks finished
executor.shutdown(); // shutdown the thread pool
System.out.println("allFiles = " + allFiles);
System.out.println("allFiles.size() = " + allFiles.size());
System.out.println("Time used: "+(System.currentTimeMillis()-startTime)+"ms");
}
}
}));
}
}
static private class SearchFileThread implements Runnable {
private int startIndex;
private int endIndex;
private File[] listFiles;
private List<String> fileList = new ArrayList<>();
private TaskFinishListener listener;
public SearchFileThread(int startIndex, int endIndex, File[] listFiles, TaskFinishListener listener) {
this.startIndex = startIndex;
this.endIndex = endIndex;
this.listFiles = listFiles;
this.listener = listener;
}
public void run() {
for (int i = startIndex; i < endIndex; i++) {
fileList.add(listFiles[i].getAbsolutePath());
}
listener.onFinish(fileList);
}
}
private interface TaskFinishListener {
void onFinish(List<String> fileList);
}
}