我的ExecutorService代码有什么问题吗?

时间:2012-10-02 13:47:15

标签: java multithreading executorservice

所以我编写了一个代码块,它将通过一个任务处理程序提交一个对象数组,我有一个实例出现程序崩溃并且没有正确关闭...这个代码会做我喜欢的吗想它应该吗?

在我看来,下面的代码应该取一个对象,将它传递给一个处理程序,然后等到最多30秒,如果该线程没有完成,则将其删除。正确?

 //Iterate through the array to submit them into individual running threads.
    ExecutorService threadPool = Executors.newFixedThreadPool(12);
    List<Future<?>> taskList = new ArrayList<Future<?>>();
    for (int i = 0; i < objectArray.length; i++) {
        Future<?> task = threadPool.submit(new ThreadHandler(objectArray[i], i));
        taskList.add(task);
        Thread.sleep(500);
    }

    //Event handler to kill any threads that are running for more than 30 seconds (most threads should only need .25 - 1 second to complete.
    for(Future future : taskList){
        try{
            future.get(30, TimeUnit.SECONDS);
        }catch(CancellationException cx){ System.err.println("Cancellation Exception: "); cx.printStackTrace();
        }catch(ExecutionException ex){ System.err.println("Execution Exception: ");ex.printStackTrace();
        }catch(InterruptedException ix){ System.err.println("Interrupted Exception: ");ix.printStackTrace();
        }
    }
    threadPool.shutdown(); // SHUT. DOWN. EVERYTHING.

3 个答案:

答案 0 :(得分:2)

如果工作未在30秒内完成,它将抛出TimeoutException。您需要使用Future.cancel()才能取消该帖子。它将中断Future表示的正在运行的线程。

答案 1 :(得分:2)

  

程序崩溃但没有正确关闭

从评论看来,程序挂起而不是崩溃。请使用正确的术语来描述将来的问题。似乎某种远程Web请求没有完成。如果可能,请确保在所有http客户端和其他连接上设置IO超时。 thread.interrupt()很可能停止网络请求,除非它正在使用NIO可中断渠道。

例如:

HttpClientParams params = new HttpClientParams();
params.setSoTimeout(socketTimeoutMillis);
HttpClient httpClient = new HttpClient(params);
  

在我看来,下面的代码应该取一个对象,将它传递给一个处理程序,然后等到最多30秒,如果该线程没有完成,则将其删除。正确?

你的代码并没有这么做。

  • 您应该在提交完上一个任务后立即致电threadPool.shutdown()。线程池停止接受新任务,但提交的任务继续运行。
  • 如果您要“杀死”已经运行超过30秒的任何任务,您应该使用threadPool.shutdownNow(),这将实际中断仍在threadPool中运行的作业。当future.cancel()超时时,您也可以使用其他人推荐的get()来调用各个任务。
  • 请注意,要使中断工作,您的ThreadHandler必须检查Thread.currentThread().isInterrupted()才能看到中断。中断还会导致睡眠,等待和其他方法抛出InterruptedException。有关详细信息,请参阅my answer here

答案 2 :(得分:2)

//Event handler to kill any threads that are running for more than 
//30 seconds (most threads should only need .25 - 1 second to complete.

不,它不会,你只是不等他们完成了。使用cancel将其彻底杀死:

for(Future future : taskList){
    try{
        future.get(30, TimeUnit.SECONDS);
    }catch(TimeoutException ex) {
        future.cancel(true);
    }
}

此外,您应该在致电shutdown后确认执行人已完成:

threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);