我正在使用由Apache AsyncRestTemplate支持的Spring HttpAsyncClient。我的配置基于此blog entry。
在JUnit中运行我的异步代码时,一切都干净利落。我怀疑这是因为当测试方法退出时,JUnit会杀死所有正在运行的线程。
@Test
public void loadFirstSISOfferingFromFactory() throws Exception {
CourseOfferingService factoryCourseService = ValenceServiceFactory.getCourseOfferingService();
BlockingQueue<CourseOffering> queue = factoryCourseService.getAllCourseOfferings();
CourseOffering course = queue.take();
LOG.info( course.toString() );
}
当我在main()方法中运行相同的测试时(就像部署时一样),I / O调度程序线程无法退出。
public static void main( final String args[] ) throws Exception {
CourseOfferingService courseService = ValenceServiceFactory.getCourseOfferingService();
BlockingQueue<CourseOffering> queue = courseService.getAllCourseOfferings();
CourseOffering course = queue.take();
System.out.println( course.toString() );
}
代码正常工作 - 也就是说,它连接到我期望的REST API,加载正确的数据,执行回调方法,并填充队列。 ValenceServiceFactory生成Spring bean(我正在使用这个非Spring启用的项目来访问我的服务)。但是,当所有连接都空闲且主线程已完成时,I / O调度程序线程仍然存在。
这是我的春季配置:
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate( new HttpComponentsClientHttpRequestFactory() );
restTemplate.setErrorHandler( new DefaultResponseErrorHandler() {
@Override
public void handleError( ClientHttpResponse response ) throws IOException {
// Do nothing when error is found.
// Hopefully the status code will be passed to the ResponseEntity
}
} );
return restTemplate;
}
@Bean
public AsyncRestTemplate asyncRestTemplate() throws IOReactorException {
// Configure Apache Http Client
PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager( //
new DefaultConnectingIOReactor( IOReactorConfig.DEFAULT ) );
connectionManager.setMaxTotal( 1000 ); //Total Connections
connectionManager.setDefaultMaxPerRoute( 900 ); //Max connections per host
RequestConfig config = RequestConfig.custom() //
.setConnectTimeout( 60 * 1000 ) // milliseconds
.build();
CloseableHttpAsyncClient httpclient = HttpAsyncClientBuilder.create() //
.setConnectionManager( connectionManager ) //
.setDefaultRequestConfig( config ) //
.build();
AsyncRestTemplate restTemplate = new AsyncRestTemplate( //
new HttpComponentsAsyncClientHttpRequestFactory( httpclient ), restTemplate() );
return restTemplate;
}
我想在主方法结束时删除System.exit(0)
,但是如果有一个正在运行的后台进程我想要完成,它将立即被杀死,而不是等待完整。
基本上,我正在寻找等效的java.util.concurrent.ExecutorService.shutdown()
和.awaitTermination()
,除了AsyncRestTemplate或HttpAsyncClient。理论上,在每个调度程序线程空闲一段时间后,可以进行干净关闭。
这可能吗?我被迫使用System.exit()
吗?
提前致谢。