【问题标题】:Is there a way to make a thread pool thread to quit processing the given task?有没有办法让线程池线程退出处理给定的任务?
【发布时间】:2018-08-27 04:05:47
【问题描述】:

我有一个场景,执行器线程池中的 n 个线程调用不同的 Web 服务,但所有线程都应在指定的时间限制内完成其任务,否则所有池线程应退出处理其任务并返回其执行器池。

我编写的代码运行良好,但唯一困扰我的情况是我无法取消已经启动的任务,即等待外部 Web 服务响应的线程。

我了解 future.cancel(true) 无法帮助我实现这一目标,但有什么方法可以实现我想要的吗?

我无法通过池线程无限期地等待 Web 服务响应。提前致谢!

    public class CallProductServiceTask implements Callable<Object>{

      public Object call(){
          // Call to product service
          // For SOAP Client 
          ProductRequest productRequest = new ProductRequest("prodId"); 
          ProductResponse response = (ProductResponse)webServiceTemplate.marshalSendAndReceive(productRequest); 
           // For REST Client 
          ResponseEntity<ProductResponse> response = restTemplate.exchange(productResourceUrl, HttpMethod.POST, productRequest, ProductResponse.class); 
      }
    }

    class Test{

       ExecutorService executor = Executors.newFixedThreadPool(2);

       public static void main(String args[]){
          Future ft = executor.submit(new CallProductServiceTask());
          try{
             Object result = ft.get(3, TimeUnit.SECONDS);
          } catch (TimeoutException e) {
                boolean c = future.cancel(true);
                System.out.println("Timeout " + c);
          } catch (InterruptedException | ExecutionException e) {
                 System.out.println("interrupted");
          }
         System.out.println("END");
      }
    }

【问题讨论】:

  • // Call to product service 需要可中断
  • // Call to product service 长什么样子?
  • 就像这里显示的那样。 // 对于 SOAP 客户端 ProductRequest productRequest = new ProductRequest("prodId"); ProductResponse 响应 = (ProductResponse) webServiceTemplate.marshalSendAndReceive(productRequest); // 对于 REST 客户端 ResponseEntity response = restTemplate.exchange(productResourceUrl, HttpMethod.POST, productRequest, ProductResponse.class);
  • 如果我的设计不正确,或者有其他正确的方法可以满足这种情况,请告诉我?
  • 如果你使用的是posix线程,应该有一个取消函数在线程id上执行,例如在C中有一个pthread_cancel( pthread_t *tid),这个函数取消一个线程的执行

标签: java multithreading future executorservice threadpoolexecutor


【解决方案1】:

我认为您的问题是管理对产品服务的请求。如果您为每个请求正确配置读取超时,您将不必担心中断任务执行。

您将在此处了解如何为WebServiceTemplateRestTemplate 设置读取超时:

How to set read timeout in WebServiceTemplate?
How to set read timeout in RestTemplate?

我将为基于RestTemplate 的方法编写一些伪代码。 (我不记得WebServiceTemplate 抛出了什么异常。不过,想法保持不变。)

CallProductServiceTask#call

try {
    final ResponseEntity<?> response = restTemplate.exchange(...);

    return parseResponse(response);
} catch (RestClientException e) {
    final Throwable cause = e.getCause();

    if (cause != null && cause instanceof SocketTimeoutException) {
        throw new BusinessLogicException(cause);
    }
}

Test.main

try {
    future.get();
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (ExecutionException e) {
    final Throwable cause = e.getCause();

    if (cause != null && cause instanceof BusinessLogicException) {
        System.out.println("The task was interrupted...");
    }
}

【讨论】:

  • 你好安德鲁,非常感谢你的建议。我认为从用例的角度来看,您的建议肯定对我有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 2020-01-31
  • 2012-03-03
  • 2021-11-09
  • 2022-01-18
  • 1970-01-01
相关资源
最近更新 更多