我有一个ProcessesManager
班extends Thread
。在run()
方法中,我这样做:
public void run() {
while(true)
synchronized (GlobalVariables.queue) {
while (GlobalVariables.queue.isEmpty())
// Threads are waiting here...
GlobalVariables.queue.wait();
// Get the next work item off of the queue
work = GlobalVariables.queue.remove();
}
}
在main方法中,我创建了ProcessesManager
类的四个实例(线程)。
for (int i = 0; i < 4; i++) {
ProcessesManager processesManager = new ProcessesManager();
processesManager.start();
}
他们正在等待queue
。队列在开始时为空,然后我开始填充队列,线程开始处理队列项。现在,线程同时从队列中删除/添加项目。没有&#34;结束&#34;到程序本身。但要明确的是,程序的结尾是1.队列是空的。 2.所有线程都在等待,不再工作了。
现在我想实现一个检查三个条件的方法:
检查队列是否为空。
检查所有线程是否在等待,没有线程正在进行任何工作。
检查它是否不是应用程序的开头(因为在开始时,上述两个条件将持续一段时间)。
如果满足以上所有条件,我想退出/关闭应用程序。
我只需检查GlobalVariables.queue.isEmpty()
方法即可查看条件1。但我不知道如何检查所有线程是否处于等待状态。我也可以找到第三个条件的解决方案。
如何检查所有线程是否只是在等待而不再工作?
修改
我正在使用本教程:http://www.drdobbs.com/parallel/java-concurrency-queue-processing-part-1/232700457。有没有办法知道程序的结束?
答案 0 :(得分:0)
对条件使用ReentrantLock,它有许多方法可以解决您的问题 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html
答案 1 :(得分:0)
要清楚,程序结束时为1.队列为空。 2.所有线程都在等待,不再工作了。
假设您的工作线程平均比填充队列的生产者更快。在这种情况下,队列在大多数时间都是空的,工人大部分时间都在等待。在你的计划中,如果队列是空的并且工人都是空闲的,那么就无法判断是否因为生产者真的已经完成,或者是因为生产者是添加下一个项目有点慢。
也许在你的应用程序中,制作人永远不会落后于此,但你的代码中没有任何内容保证它永远不会落后于此。
您正在实现的东西称为线程池(例如,像java.util.concurrent.ThreadPoolExecutor
)。在大多数线程池实现中,生产者可以通过某种方式显式关闭池(例如,ThreadPoolExecutor.shutdown()
)
实现关闭的一种方法是使用 poison pill - 一个特殊任务,告诉工作线程将其终止。当关闭池时,调用者只需加载队列至少与为队列服务的工作线程一样多的毒丸。