【问题标题】:Pass status of child thread to its parent thread after excecution执行后将子线程的状态传递给其父线程
【发布时间】:2012-08-30 09:15:12
【问题描述】:

我想从一个可运行的线程中抛出一个异常,但它不可能从线程中抛出,所以我们可以将 chlild 线程的状态(任何异常)传递给父线程吗?。

我读到了thread.join(),但在这种情况下,父线程一直等到子线程完成它的执行。

在我的情况下,我的父线程在一段时间后一个接一个地启动线程,但是当任何线程抛出异常时,它应该将失败通知给客户端,这样父线程就不会启动其他线程。

有什么方法可以实现吗?谁能帮我解决这个问题。

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    要详细说明@zeller 的答案,您可以执行以下构造:

    //Use a Callable instead of Runnable to be able to throw your exception
    Callable<Void> c = new Callable<Void> () {
        public Void call() throws YourException {
            //run your task here which can throw YourException
            return null;
        }
    }
    
    //Use an ExecutorService to manage your threads and monitor the futures
    ExecutorService executor = Executors.newCachedThreadPool();
    List<Future> futures = new ArrayList<Future> ();
    
    //Submit your tasks (equivalent to new Thread(c).start();)
    for (int i = 0; i < 5; i++) {
        futures.add(executor.submit(c));
    }
    
    //Monitor the future to check if your tasks threw exceptions
    for (Future f : futures) {
        try {
            f.get();
        } catch (ExecutionException e) {
            //encountered an exception in your task => stop submitting tasks
        }
    }
    

    【讨论】:

    • 但是如果我不知道我的应用程序将调用多少个线程,那么我的期货列表将不会被修复。??那怎么监控呢??
    • 如果每次提交新任务时将 executor.submit 返回的 futures 存储在列表中,则不需要知道运行了多少线程,只需要跟踪那些期货。
    • ok.. 因为我从 2-3 个类中调用了这个可调用方法,并且只使用了一个由 executor.submit 返回的期货列表。
    • 是的,就是这样。或者,您可以使用 CompletionService,它会在任务完成后返回它们。例如:stackoverflow.com/questions/11578326/…
    【解决方案2】:

    您可以使用Callable&lt;Void&gt; 代替Runnable,也可以使用ExecutorService 代替自定义线程池。 Callable-s call 抛出异常。
    使用ExecutorService 还可以管理正在运行的任务,跟踪Future-s 返回的submit。这样你就可以知道异常、任务完成等等。

    【讨论】:

      【解决方案3】:

      使用并发集合在父线程和子线程之间进行通信。在您的 run 方法中,执行 try/catch 块以接收所有异常,如果发生异常,请将其附加到用于与父级通信的集合中。父级应检查集合以查看是否发生任何错误。

      【讨论】:

        【解决方案4】:

        不实现Runnable接口,而是实现Callable接口,返回值给父线程。

        我想从一个可运行的线程中抛出一个异常,但它不可能从线程中抛出,所以我们可以将 chlild 线程的状态(任何异常)传递给父线程吗?。

        --> @assylias 说:不要通过返回值传递异常,只需抛出它。然后,您可以从父线程中捕获它,通常使用 future.get();调用将引发 ExecutionException。

        另外,Callable.call() throws Exception 这样你就可以直接扔了。

        【讨论】:

        • 我不同意你最后的评论:不要通过返回值传递异常,只需抛出它。然后,您可以从父线程中捕获它,通常使用 future.get(); 调用,这将引发 ExecutionException
        • @assylias :我知道在 Runnable 的情况下,我们必须在线程中处理它。我只知道方法:使用 Callable 接口。在实践中,我从未使用过 Callable。我会尽快更新答案。
        • @assylias : 顺便说一句,call() throws Exception,我们需要使用future.get();获取它吗
        • 我已经用一个例子添加了答案
        猜你喜欢
        • 2021-12-17
        • 2011-08-16
        • 2020-02-21
        • 1970-01-01
        • 2019-03-08
        • 1970-01-01
        • 2013-04-27
        • 2017-05-31
        • 1970-01-01
        相关资源
        最近更新 更多