我有一个ThreadPoolExecutor:
ThreadPoolExecutor service = new ThreadPoolExecutor(N_THREADS, N_THREADS, 0L, TimeUnit.MILLISECONDS, blockingQueue, rejectedExecutionHandler);
该服务执行实现Runnable接口的线程。每个线程处理磁盘上的文件。我发现在几个小时后,两个线程(或核心取决于Linux中显示的htop)正在运行并且已经运行了13个小时。更糟糕的是,剩下的核心没有显示任何活动,就好像他们正在等待两个线程完成一样。
问题: 1 - 我已经阅读了很多关于如何解决这个问题但没有结论的内容。据我所知,你不能使用ThreadPoolExecutor停止Runnable,因为它是一个只运行的独立线程。使用Future框架:
Future<?> f = f.get(submittedtask,XX)
允许您设置超时并获取未来结果,但是获取所有线程的块有效地使实现串行。是否可以在给定时间后使用threadpoolexecutor中断Runnable,将线程返回到池中,以便它可以拾取新任务并继续。
2 - 我最关心的是,使用htop,我看到两个线程/核心正在运行而没有其他核心/线程正在运行,尽管许多任务仍在等待执行(即有许多文件需要处理)。有什么见解吗?
答案 0 :(得分:1)
您可以创建第二个预定的线程池,您可以为每个返回的Future
提交取消任务。在给定超时后的每个任务都将检查它是否已关联Future
,如果没有,则取消它。取消会触发线程中断,因此您可能需要通过检查中断的标志来支持您的任务:Thread.interrupted()
。
第二个线程池的大小可能是最小的,即1,因为这个作业占用的CPU时间最短。
代码示例:
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
...
while(...){
final Future<?> f = pool.submit(...);
service.schedule(new Runnable() {
@Override
public void run() {
if(!f.isDone()){
f.cancel(true);
}
}
}, 1, TimeUnit.MINUTES);
}
service.awaitTermination(1, TimeUnit.MINUTES);
service.shutdown();
答案 1 :(得分:0)
您可以告诉线程希望到interrupt
:
中断是线程的指示,它应该停止它正在做的事情并做其他事情。
您可以使用Future.cancel(true)
中断您的主题。您可以通过检查其Thread.interrupted()
状态来实现Runnable,并遵守该愿望。
答案 2 :(得分:0)
要查看有关进程线程运行的详细信息:
ps -eLf | grep <PROCESS_PID>
因为htop会显示正在运行的进程列表,其中每个进程至少有一个线程。