Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 运行thread类的多个实例以读取多个文件_Java_Multithreading_Functional Programming - Fatal编程技术网

Java 运行thread类的多个实例以读取多个文件

Java 运行thread类的多个实例以读取多个文件,java,multithreading,functional-programming,Java,Multithreading,Functional Programming,所以我有一个可调用的类,它处理给定的文本文件,然后生成一个输出文本文件。我想用它自己的线程处理每个文件,但是我对用相同的对象启动线程和用不同的线程对象启动线程的区别感到困惑。除了输入文件不同之外,两个线程做完全相同的事情。最初我想使用一个线程对象,但如果我使用一个线程对象,我将如何加载不同的文件 比如说 ExecutorService pool = Executors.newFixedThreadPool(2); Runner test = new Runner("file1.

所以我有一个可调用的类,它处理给定的文本文件,然后生成一个输出文本文件。我想用它自己的线程处理每个文件,但是我对用相同的对象启动线程和用不同的线程对象启动线程的区别感到困惑。除了输入文件不同之外,两个线程做完全相同的事情。最初我想使用一个线程对象,但如果我使用一个线程对象,我将如何加载不同的文件

比如说

    ExecutorService pool = Executors.newFixedThreadPool(2);

    Runner test = new Runner("file1.txt");

    Future<String> ret = pool.submit(test);

    Future<String> ret2 = pool.submit(test);
VS

我的问题/因素

上面的示例清楚地命名了textfiles,在实际实现中,这些文件是未知的,因此通过迭代循环进行访问。 如果我使用单线程对象,那么我将如何处理不同的文件 如果使用两个独立的线程对象,那么我仍然需要担心同步问题。
提前感谢

两种方法都是可能的:您可以在每个任务中使用不同的对象,您可以共享对象,也可以混合使用这两种方法。在大多数情况下,最简单的解决方案是为每个任务创建一个对象。你的例子也是如此。对于循环,我可以如下所示:

List<Future<String>> futures = new ArrayList<>();
for (String pathname : pathnames) {
    futures.add(pool.submit(new Runner(pathname));
}
for (Future<String> future : futures) {
    ...
}
也可以共享一个对象。然而,这有点复杂

class Worker implements Callable<String> {
    private final List<String> pathnames;
    private final AtomicInteger index = new AtomicInteger();
    public Worker(List<String> pathnames) {
        this.pathnames = pathnames;
    }
    public String call() {
        String pathname = list.get(index.getAndIncrement());
        ...
        return ...;
    }
}

// caller
Worker worker = new Worker(pathnames);
List<Future<String>> futures = new ArrayList<>();
for (String pathname : pathnames) {
    futures.add(pool.submit(worker));
}
如您所见,工作程序必须获取路径名,而不是将路径名传递给工作程序,因为后者不能直接用于executor框架。还需要进行同步。

这里没有看到任何线程对象。我看到Runnable的实例。我不知道您是否需要使用synchronized,因为您没有显示任何代码。此外,多线程文件IO是一种反模式—除非您对文件进行了非常繁重的处理或采用某种SSD RAID,否则它会使速度变慢。
class Worker implements Callable<String> {
    private final List<String> pathnames;
    private final AtomicInteger index = new AtomicInteger();
    public Worker(List<String> pathnames) {
        this.pathnames = pathnames;
    }
    public String call() {
        String pathname = list.get(index.getAndIncrement());
        ...
        return ...;
    }
}

// caller
Worker worker = new Worker(pathnames);
List<Future<String>> futures = new ArrayList<>();
for (String pathname : pathnames) {
    futures.add(pool.submit(worker));
}