运行多个线程类实例以读取多个文件

时间:2014-04-05 10:28:53

标签: java multithreading functional-programming

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

例如

    ExecutorService pool = Executors.newFixedThreadPool(2);

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

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

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

VS

    ExecutorService pool = Executors.newFixedThreadPool(2);

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

    Runner test2 = new Runner("file2.txt");

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

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

我的问题/因素

  1. 上面的例子清楚地命名了文本文件,在实际实现中,文件是未知的,因此通过迭代循环来访问。
  2. 如果我要使用单个线程对象,那么我将如何处理不同的文件
  3. 如果使用两个单独的线程对象,那么我仍然需要担心同步。
  4. 提前致谢

1 个答案:

答案 0 :(得分:0)

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

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));
}

正如您所看到的, worker 必须获取路径名,而不是将路径名传递给 worker ,因为后者不能直接用< em> executor 框架。还需要同步。