【问题标题】:ForEach loop in interrupting and joining threadsForEach 循环中断和加入线程
【发布时间】:2019-09-30 19:01:03
【问题描述】:

有一个 ArrayList<Wheel> 轮子,作为 Wheel 一个扩展 Thread 的类,如果我有以下情况会发生什么:

wheels.forEach(a -> {
                try{
                    a.interrupt();
                    a.join();
                }catch(InterruptedException exception){}
            });

这段代码的指令顺序是什么?

现在我认为它会如下:1)a 被中断,2)我的 main 线程将加入 a,并且只有在 a 完成之后,forEach 循环才会继续通过剩余的项目,对吗?

是否可以在 ArrayList 中进行迭代,其中所有线程将被中断并加入,而无需手动逐项进行?

非常感谢您的帮助!

【问题讨论】:

  • 你可以把它分成 2 个循环。一种中断线程。然后是第二个加入每个人。
  • @JohnnyMopp。 Sute,但它不会有同样的问题吗?第二个将进行主要等待,然后等待,然后再次等待。也许我看错了,我想要的是所有线程都“同时”加入(不完全是明显的,但大致上)并且只等待一次。
  • 是的,但是对于 2 个循环,您首先在第一个循环中同时告诉所有线程“退出时间”(实际上)。所以每个线程同时开始关闭。然后,在第二个循环中,你 join a,假设需要 4 秒。然后你 join b 但 b 只用了 2 秒就关闭了,所以当你尝试 join 它时 b 已经完成,join 马上返回。所以整个事情需要 4 秒(任何线程需要关闭的最长时间),而不是 6 秒(所有线程的累积时间)。我认为这是你的目标。
  • @JohnnyMopp 是的!就是这样!谢谢你这么详细的回答:)
  • @JohnnyMopp 虽然这不是答案,只是评论。如果你把它放在一个 answer 中,人们将能够对其进行投票、接受等。提示,提示。

标签: java multithreading foreach


【解决方案1】:

Johnny 的评论对于您当前的实施是正确的。您也可以遵循另一条路径,例如;

您可以在 Wheel 类中实现 Runnable(或 Callable),而不是扩展线程,并将您的任务列表提交给执行器服务。通过这种方式,您可以获得线程池(重用线程)的好处,并使用关闭并等待所有线程完成的内置功能。

例子:

ExecutorService executor = Executors.newFixedThreadPool(5);
wheels.foreach(wheel -> executor.submit(wheel));

//when you want to shutdown
executor.shutdownNow(); // this will send interrupt to thread pool threads.
executor.awaitTermination(10, TimeUnit.SECONDS); 
// block the current thread until executor finishes or timeout expires. 
// You could give a bigger timeout or call this with in a while loop to ensure 
// executor definitely finished.
// like this: while(!executor.awaitTermination(10, TimeUnit.SECONDS));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多