0

所以我编写了一段代码,它将通过任务处理程序提交一组对象,我有一个实例出现在程序崩溃并且没有正确关闭的地方......这段代码会做我认为它应该做的事情吗?

在我看来,以下代码应该获取一个对象,将其传递给处理程序,然后等待最多 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.
4

3 回答 3

2

程序崩溃并且没有正确关闭

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

例如:

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

在我看来,以下代码应该获取一个对象,将其传递给处理程序,然后等待最多 30 秒,如果该线程尚未完成,则将其终止。正确的?

您的代码并没有完全做到这一点。

  • 您应该threadPool.shutdown()在向它提交最后一个任务后立即调用。线程池停止接受新任务,但提交的任务继续运行。
  • 如果你想“杀死”任何已经运行超过 30 秒的任务,你应该使用threadPool.shutdownNow()which 实际上会中断仍在threadPool. 您还可以future.cancel()在超时时按照其他人的建议调用各个任务get()
  • 请注意,要使中断正常工作,您ThreadHandler必须进行检查Thread.currentThread().isInterrupted()才能看到中断。中断还会导致 sleep、wait 和其他方法抛出InterruptedException. 有关更多详细信息,请参阅我的答案
于 2012-10-02T13:51:23.757 回答
2

TimeoutException如果工作未在 30 秒内完成,它将抛出。您需要使用Future.cancel()来取消线程。它将中断以 Future 为代表的正在运行的线程。

于 2012-10-02T13:50:46.073 回答
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);
于 2012-10-02T13:55:12.087 回答