中断Runnable需要几个小时

时间:2014-01-12 08:55:35

标签: java multithreading runnable threadpoolexecutor

我有一个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,我看到两个线程/核心正在运行而没有其他核心/线程正在运行,尽管许多任务仍在等待执行(即有许多文件需要处理)。有什么见解吗?

3 个答案:

答案 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会显示正在运行的进程列表,其中每个进程至少有一个线程。