java中的执行器
我试图使用 FixedThreadPool
运行 ExecutorService
对象,但遇到了问题。
我预计该程序将在纳秒内运行,但它被挂起。我发现我需要将 Semaphore 与它一起使用,以便队列中的项目不会被添加。
有什么方法可以让我知道池中的所有线程都已使用。
基本代码...
static ExecutorService pool = Executors.newFixedThreadPool(4);
static Semaphore permits = new Semaphore(4);
try {
permits.acquire();
pool.execute(p); // Assuming p is runnable on large number of objects
permits.release();
} catch ( InterruptedException ex ) {
}
这段代码被挂起,我真的不知道为什么。如何知道池当前是否正在等待所有线程完成?
I was trying to run ExecutorService
object with FixedThreadPool
and I ran into problems.
I expected the program to run in nanoseconds but it was hung. I found that I need to use Semaphore
along with it so that the items in the queue do not get added up.
Is there any way I can come to know that all the threads of the pool are used.
Basic code ...
static ExecutorService pool = Executors.newFixedThreadPool(4);
static Semaphore permits = new Semaphore(4);
try {
permits.acquire();
pool.execute(p); // Assuming p is runnable on large number of objects
permits.release();
} catch ( InterruptedException ex ) {
}
This code gets hanged and I really don't know why. How to know if pool is currently waiting for all the threads to finish?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
默认情况下,如果您向池提交超过 4 个任务,则多余的任务将排队,直到有线程可用。
您在评论中引用的博客使用信号量来限制可以立即排队的工作量,这对您来说不会成为问题,直到您有数千个任务排队并且它们开始占用可用内存。无论如何,有一种更简单的方法可以做到这一点 - 构造一个 ThreadPoolExecutor 具有有界队列。* 但这不是您的问题。
如果您想知道任务何时完成,请注意
ExecutorService .submit()
返回一个Future
对象,可用于等待任务完成:如果您有多个任务并希望等待所有任务完成,则可以存储每个 < code>Future 在列表中,然后依次调用每个
get()
,或者调查ExecutorService.invokeAll()
(本质上是相同的,但在单个方法调用)。您还可以判断任务是否已完成:
最后,请注意,即使您的任务已完成,如果您没有调用 shutdown()<,您的程序也可能不会退出(因此看起来“挂起”) /code> 在线程池上;原因是线程仍在运行,等待执行更多工作。
*编辑:抱歉,我刚刚重新阅读了我的答案并意识到这部分是不正确的 - ThreadPoolExecutor 向队列提供任务,如果不接受则拒绝它们,因此有界队列与信号量方法。
By default, if you submit more than 4 tasks to your pool then the extra tasks will be queued until a thread becomes available.
The blog you referenced in your comment uses the semaphore to limit the amount of work that can be queued at once, which won't be a problem for you until you have many thousands of tasks queued up and they start eating into the available memory.
There's an easier way to do this, anyway - construct a ThreadPoolExecutor with a bounded queue.* But this isn't your problem.If you want to know when a task completes, notice that
ExecutorService.submit()
returns aFuture
object which can be used to wait for the task's completion:If you have several tasks and want to wait for all of them to complete, either store each
Future
in a list and then callget()
on each in turn, or investigateExecutorService.invokeAll()
(which essentially does the same but in a single method call).You can also tell whether a task has completed or not:
Finally, note that even if your tasks are complete, your program may not exit (and thus appears to "hang") if you haven't called
shutdown()
on the thread pool; the reason is that the threads are still running, waiting to be given more work to do.*Edit: sorry, I just re-read my answer and realised this part is incorrect - ThreadPoolExecutor offers tasks to the queue and rejects them if they aren't accepted, so a bounded queue has different semantics to the semaphore approach.
您不需要信号量。
如果你挂了,可能是因为螺纹在其他地方锁住了。
在调试器中运行代码,当它挂起时暂停它并查看线程正在做什么。
You do not need the Semaphore.
If you are hanging it is probably because the threads are locking themselves elsewhere.
Run the code in a Debuger and when it hangs pause it and see what the threads are doing.
您可以更改为使用 ThreadPoolExecutor 。它包含一个
getActiveCount()
方法,该方法返回活动线程的近似计数。为什么它是近似值我不确定。You could change to using a ThreadPoolExecutor. It contains a
getActiveCount()
method which returns an approximate count of the active threads. Why it is approximate I'm not sure.