如何使用java多线程扫描多个目录

如何使用java多线程扫描多个目录,java,multithreading,Java,Multithreading,问题是,您必须列出给定目录中的文件名,您已经给出了一个目录结构,其中包含一些子目录和一些文件 我做了一些代码,但它不工作,你能帮我做它的正确方法是什么吗 代码 public class Test { public static void main(String[] args) { RunableExample run = new RunableExample(); Thread th = new Thread(run, "thread1"); String directo

问题是,您必须列出给定目录中的文件名,您已经给出了一个目录结构,其中包含一些子目录和一些文件

我做了一些代码,但它不工作,你能帮我做它的正确方法是什么吗

代码

public class Test {
public static void main(String[] args) {
    RunableExample run = new RunableExample();
    Thread th = new Thread(run, "thread1");
    String directoryName = "C:\\Users\\GUR35893\\Desktop\\CleanupMTM";
    File directory = new File(directoryName);
    File[] fList = directory.listFiles();
    RunableExample.MyList = new ArrayList<File>();
    for (File file : fList) {
        RunableExample.MyList.add(file);
    }
    try {
        th.start();
    } catch (Exception e) {

    }
  }
 }

 public class RunableExample implements Runnable {
public static List<File> MyList;
int count = 0;
File filepath;

public void run() {
    try {
        while (count < MyList.size()) {
            System.out.println(Thread.currentThread().getName() + ">>>>"
                    + MyList.size() + " >>>>> " + count);
            filepath = MyList.get(count);

            if (filepath != null && filepath.isFile()) {

                System.out.println(Thread.currentThread().getName() + " >>"
                        + filepath.getAbsolutePath());
            } else {
                synchronized (this) {
                    if (filepath != null) {
                        // System.out.println("Else");
                        RunableExample run3 = new RunableExample();
                        Thread th3 = new Thread(run3, "thread" + count);
                        File[] fList = filepath.listFiles();
                        // System.out.println("Else1");
                        for (File file : fList) {
                            MyList.add(file);
                        }
                        th3.start();
                    }
                }
            }
            count++;
        }
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println(e);

    }

}
}
公共类测试{
公共静态void main(字符串[]args){
RunableExample run=新的RunableExample();
螺纹th=新螺纹(运行,“螺纹1”);
String directoryName=“C:\\Users\\GUR35893\\Desktop\\CleanupMTM”;
文件目录=新文件(目录名);
File[]fList=directory.listFiles();
RunableExample.MyList=新的ArrayList();
for(文件:fList){
RunableExample.MyList.add(文件);
}
试一试{
th.start();
}捕获(例外e){
}
}
}
公共类Runnable示例实现Runnable{
公共静态列表;
整数计数=0;
文件路径;
公开募捐{
试一试{
而(计数>>>”
+MyList.size()+“>>>>”+计数);
filepath=MyList.get(计数);
if(filepath!=null&&filepath.isFile()){
System.out.println(Thread.currentThread().getName()+“>>”
+getAbsolutePath());
}否则{
已同步(此){
if(filepath!=null){
//系统输出打印项次(“其他”);
RunableExample run3=新的RunableExample();
螺纹th3=新螺纹(run3,“螺纹”+计数);
File[]fList=filepath.listFiles();
//系统输出打印项次(“Else1”);
for(文件:fList){
MyList.add(文件);
}
th3.start();
}
}
}
计数++;
}
}捕获(例外e){
e、 printStackTrace();
系统输出打印ln(e);
}
}
}
如果您有一个目录(包括子目录)并希望列出所有文件。 最简单但有效的方法是遍历一个目录,只有两个选项,一个是文件,一个是目录

如果它是一个文件,只需命名它,不要为它生成新线程。 如果它是一个目录,则生成一个新线程,并在新生成的线程中重复使用相同的代码来遍历该目录中的文件或子目录


如果您能提供一个样本输出,那么我们可能会进一步提供帮助。但在此之前,我在代码中没有看到任何同步的使用。

实现@Himanshu Answer

import java.io.File;

class Lister extends Thread{
    String basepath;

    Lister(String basepath){
        this.basepath = basepath;
    }
     @Override
     public void run(){
         File rootDir = new File(basepath);

         for(File f : rootDir.listFiles()){
             if(f.isDirectory())
                 new Lister(f.toString()).start();
             else
                 System.out.println(f);
         }
     }
}

class Main {
    public static void main(String[] args) {

        new Lister("/").start();
    }
}

这段代码可以工作,但请确保它不会为巨大的目录树造成内存溢出。为此,您可以添加额外的检查以生成所需的唯一目录。

此问题很可能是I/O绑定的(除非您搜索多个物理磁盘),因此使用多线程不会是一个大胜利。Himanshu,您是正确的,但我的要求是,只要找到新目录,就为它生成新线程,以提高处理时间。你给出的建议只适用于一个线程。如果有数千个子目录和文件可用,则响应时间将增加。因此,目标是为每个目录生成线程。将为每个目录生成新线程,请再次检查代码!这是一个单线程解决方案。当子目录的数量增加时,处理时间会增加。仔细阅读我的答案的第2段。每个子目录都意味着一个新线程,理想情况下,我会使用FixedThreadPoolExecutor来控制它