在main()退出后如何杀死Apache HttpClient I / O Dispatcher线程?

时间:2015-06-05 18:54:55

标签: java multithreading spring apache-httpclient-4.x resttemplate

我正在使用由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调度程序线程仍然存在。

IO dispatcher threads in the debugger

这是我的春季配置:

@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()吗?

提前致谢。

0 个答案:

没有答案