【问题标题】:Control Multithreading in JavaJava中的控制多线程
【发布时间】:2013-08-04 13:39:21
【问题描述】:

我有一个“可运行”线程,它正在启动几个“可调用”线程,我想在以上所有线程完成工作时显示结果。

最好的方法是什么?

我的代码如下

Connector.java(启动可运行线程)

  public class Connector {
                      private static void anyFileConnector() {
                    // Starting searching Thread
                        ExecutorService executor = Executors.newFixedThreadPool(100);
                        executor.submit(traverse, executor);
//HERE I WANT MY ALL SEARCH RESULTS/OUTPUT : CURRENTLY IT IS STARTING OTHER THREADS AND NOT SHOWING ME ANY RESULTS BECAUSE NONE OF THEM WAS FINISHED.(IN CONSOLE, I WAS ABLE TO SEE RESULTS FROM ALL THE THREADS
        setSearchResult(traverse.getResult());

                    executor.shutdown();
            }
    }

Traverse.java(可运行线程) 我正在使用 ExecutorCompletionService 来处理它......但它没有产生任何区别。 :(

public class Traverse implements Runnable {
    public void run() {

    ExecutorService executor = Executors.newFixedThreadPool(100);
    ExecutorCompletionService<List<ResultBean>> taskCompletionService =
            new ExecutorCompletionService<List<ResultBean>>(executor);
    try (DirectoryStream<Path> stream = Files
            .newDirectoryStream(dir)) {
                Search newSearch = new Search();
                taskCompletionService.submit(newSearch);
     }
    list.addAll(taskCompletionService.take().get());
    }
}

Search.java(可调用线程)

public class Search implements Callable<List<ResultBean>> {
 public List<ResultBean> call() {
        synchronized (Search.class) {
// It will return results
            return this.search();
        }
    }

}

【问题讨论】:

    标签: java multithreading synchronization thread-safety cyclicbarrier


    【解决方案1】:

    选择CyclicBarrier,您将能够实现这一目标。 一旦所有线程完成工作,循环屏障就会执行任务,您可以在此处打印结果。

    查看此链接以了解 CyclicBarrier 的工作情况:http://javarevisited.blogspot.com/2012/07/cyclicbarrier-example-java-5-concurrency-tutorial.html

    【讨论】:

    • 像这样创建一个 CB 实例: final CyclicBarrier cb = new CyclicBarrier(total thread count, new Runnable(){"your final Task"}); .现在将这个循环屏障的引用传递给所有线程,并确保在每个线程中调用“barrier.await();”。就是这样,一旦所有线程都完成了他们的工作,你的最终任务就会被执行。
    • 在我的情况下,我没有任何特定的“线程数”..它可以是任何数字,因为我正在遍历文件夹并在那里搜索文件......所以我可以给出一些最大值那里的号码?...或任何其他方式来处理?
    • 不,您需要事先知道总数。我的建议是在初始化 CyclicBarrier 之前进行文件夹搜索,这样你就知道自己之前的线程总数。
    • 我不能这样做...我正在一起遍历和搜索...意味着..一旦我得到一个文件...我正在启动一个搜索线程...就像我正在做的那样搜索..最后我想要所有合并的结果..但我最终没有得到结果..因为只要我点击“搜索”..它只是启动线程(遍历和搜索)和走到最后没有任何结果(因为其他人还在做遍历和搜索)
    • 任何想法??..我怎样才能实现它??
    【解决方案2】:

    Easy - 所有的 Callables 都将返回 Future 对象,您可以使用这些对象等待并通过以阻塞等待方式调用 Future.get() 来获取结果。所以你的问题只是一个 for 循环等待可调用对象上的每个未来。

    之后,只需将结果汇总返回给客户端。

    【讨论】:

      【解决方案3】:

      执行器服务的提交方法可以返回Future对象的列表。您可以为您的情况做的是在 while 循环中调用这些 Future 对象的 isDone() 方法。

      每当未来的任何任务完成时,此方法都会返回 true。您现在可以在此调用get() 方法以获取此任务返回的值。通过这种方式,您可以掌握所有未来任务的值,而无需等待任何特定任务完成(因为您的第一个未来任务可能具有最长的完成时间)

      【讨论】:

        猜你喜欢
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多