我正在使用以下代码(大纲):
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<statusModel>> futures = new ArrayList<Future<statusModel>>();
for (Map.Entry<String, String> url : urls.entrySet())
{
Future<statusModel> future = executor.submit(mycallable);
futures.add(future);
}
for (Map.Entry<String, String> url : urls.entrySet())
{
try
{
status = (statusModel) futures.get(i).get(50, TimeUnit.MILLISECONDS);
// do stuff with status
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());
}
}
executor.shutdownNow();
System.out.println("Shutdown: "+executor.isShutdown());
我的控制台说:关机:是真的
myCallable:
public statusModel call() throws Exception
{
InputStream in = null;
BufferedReader br = null;
statusModel status = new statusModel();
try
{
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
status.setStatusCode(conn.getResponseCode());
status.setUrl(urlStr);
if(status.getStatusCode()/100 == 2) // Status = OK
{ // Read JSON response }
}
catch (MalformedURLException e)
{
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if(in != null)
in.close();
if(br != null)
br.close();
}
return status;
}
有时当我反复运行此块时,我收到此错误:
2013年8月20日上午9:35:44 org.apache.catalina.core.StandardWrapper unload 信息:等待1个实例被解除分配 2013年8月20日上午9:35:45 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 严重:Web应用程序[/ Server_Status]仍在处理尚未完成的请求。这很可能造成内存泄漏。您可以使用标准Context实现的unloadDelay属性来控制请求完成所允许的时间。 2013年8月20日上午9:35:45 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 严重:Web应用程序[/ Server_Status]似乎已启动名为[pool-3-thread-6]的线程,但未能将其停止。这很可能会造成内存泄漏。
我关闭'执行者'也检查了相同。我仍然得到这个错误。我在这里做错了吗?
更新: 我是第一次使用Future。如果我需要发布更多信息以便更好地解释,请告诉我。
更新: 我尝试打印所有future.isDone()。由于某种原因超出超时的期货仍然返回isDone()= false - 没有被timout取消:(
感谢任何帮助。在此先感谢。
答案 0 :(得分:2)
shutdownNow()
会终止仍在运行的所有可能导致错误消息的作业。您可能希望shutdown()
不会让任何新作业被提交,但让排队的作业仍然执行。
此外,您需要等待期货完成,方法是调用future.get()
(如果未来尚未结束,可能会阻止)以获得结果。
for(Future<statusModel> future : futures){
statusModel model = future.get();
//do stuff with statusModel
}
编辑:现在已经发布了其他代码,我已将此附加到我的回答中:
我已经重新检查了future.get(long timeout, TimeUnit unit)
的javadoc,并没有说如果超时发生,那么将来会被取消。我还检查了Brian Goetz的Java Concurrency in Practice(这是一本很棒的书;必读),并在第147页上建议:
try{
future.get(timeout, unit);
}catch(TimeoutException e){
//task will be cancelled below
}catch(ExecutionException e){
//exception thrown in task; rethrow
//... throw new MyWrappedException(e.getCause());
}finally{
//Harmless if task already completed
future.cancel(true); //interrupt if still running
}