CountdownLatch 结合 await(maxTime) 和 countdown()

Posted

技术标签:

【中文标题】CountdownLatch 结合 await(maxTime) 和 countdown()【英文标题】:CountdownLatch combine await(maxTime) and countdown() 【发布时间】:2011-02-04 14:16:07 【问题描述】:

我有几个线程运行几乎无限的时间和迭代次数。当找到最佳解决方案时,迭代计数将重置为 0。设置最大迭代次数以防止无限循环。

当所有线程都达到最大迭代次数时,我使用倒计时锁来停止进程。换句话说,当一个线程达到最大迭代次数时,它会使用 notifyThreadStop() 通知我的主线程,当所有线程停止时,会触发 countdown()。

注意:我的线程在 FixedThreadPool ExecutorService 中运行。

我想添加一个 maxTime 锁存器。所以我做的是以下

List<Runnable> r = .... //(contains all my runnables)
myExecutorService.invokeAll(r);

if(maxtime > 0)
    mylatch.await(maxTime,TimeUnit.Seconds);
    (1)
    do stuff...
    exit;

else
    mylatch.await();
    myExecutorService.shutdownNow();
    do stuff...
    exit;

现在,我知道如果倒计时触发了闩锁,这意味着所有线程都已停止,因此我可以关闭我的 ExecutorService。

当达到最大时间时,情况并非如此。所以在(1)中,我想遍历我所有的跑步者,以文明的方式终止他们:-)。为此,我定义了一个函数 requestTermination(),简单地说,就是在我的 runnables 中将迭代计数器设置为 MaxIterationCount。

所以 (1) 会变成

    for(Runnable runner: r)
        if(r.getIsRunning())r.requestTermination();
    
    (2)

现在,我需要再次等待,直到所有线程真正停止,然后才能继续....嗯,我只是想我可以有一个额外的锁存器并使用它。

所以 (2) 会变成

    mylatch2.await();
    myExecutorService.shutdownNow();

当然,我的函数 notifyThreadStop() 需要对其进行修改,并且需要一个标志告诉它在 mylatch2 上而不是 mylatch 上执行 countdown()。

我想我刚刚回答了我的问题,但既然所有这些都已经写完,我将把它留在这里供其他人参考。

现在的问题是:有更好的处理方法吗? (1) 或 (2) 中的 shutdownNow() 是唯一需要的吗? 知道我的线程必须在退出之前关闭它们自己的日志文件并关闭它们内部的 Callable thread*ss*。

【问题讨论】:

【参考方案1】:

如果你使用 shutdownNow() 和 awaitTernimation() 这将中断所有正在运行的任务并等待它们完成。

如果任务可以被中断并在中断时正确关闭所有资源,则应该没有问题。 (如果有问题,这是你的任务代码中的一个错误,你应该修复)

【讨论】:

好的,我看过http://www.ibm.com/developerworks/java/library/j-jtp05236.html,我想我明白了。我基本上是在用我的方法 requestTermination() 重新发明***。我将把它作为手动关闭我的线程的方式。在我的代码的另一部分仍然需要它。【参考方案2】:

我想我刚刚回答了我的问题,但既然所有这些都写完了

您确实做到了 :-) 如果要添加一件事是您应该小心 RuntimeExceptions,否则,您的 shutdownNow() 可能永远不会被调用。但你已经知道了,对吧?

【讨论】:

以上是关于CountdownLatch 结合 await(maxTime) 和 countdown()的主要内容,如果未能解决你的问题,请参考以下文章

jdk1.8 J.U.C并发源码阅读------CountDownLatch源码解析

countdownlatch 导致的多线程死锁

源码分析-CountDownLatch

线程同步-CountDownLatch

线程同步工具CountDownLatch

CountDownLatch源码解析