【问题标题】:Timeout individual threads of cached thread pool缓存线程池的单个线程超时
【发布时间】:2013-04-22 21:11:27
【问题描述】:

我想在 Web 应用程序中使用线程池,它应该同时支持大量用户(约 3000 个用户)。我正在使用线程池执行的单独线程中调用 Web 服务。每当 Web 服务无法发送响应时,线程就会卡住。所以我想在 150 毫秒后停止/超时线程。这就是我现在正在做的事情:

自定义线程:

public class RetrieveDocTask implements Runnable {
public void run() {
    //gather variables
    //invoke webservice
}}

执行线程的过滤器:

public class DocFilter implements Filter {
private static ExecutorService executor = Executors.newCachedThreadPool();
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    RetrieveDocTask task=new RetrieveDocTask();
    executor.execute(task);
}}

我浏览了互联网寻找解决方案,但没有一个对我有用。有些人说使用 Future 和 callable,而有些人要求创建 ThreadPoolExecutor 并指定超时。不知道为什么它不起作用。 此外,是否可以为大量用户使用缓存池执行器。我是新手,需要尽快实施。

【问题讨论】:

    标签: multithreading threadpool


    【解决方案1】:

    确实,未来是您在这里所需要的。假设您的类 RetriveDoc 实际上返回一个字符串。

     private static final class RetrieveDoc implements Callable<String>{
          @Override
          public String call() throws Exception {
              //do some computation and retirieve doc
              return "DocAsString";
          }
     }
    
    
     ExecutorService service = Executors.newFixedThreadPool(1);
     Future<String> futureResponse = service.submit(new RetrieveDoc());
     //this will blokc for only 150 milliseconds
     String response = null;
     try{
          response = futureResponse.get(150, TimeUnit.MILLISECONDS);
     } catch(TimeoutException e){
         System.out.println("TimeoutException happended");
     }
    
     if(response == null){
          //do something
     }
    

    【讨论】:

    • 为了测试,我放置了 String response = futureResponse.get(5, TimeUnit.MINUTES);当我在 call 方法中设置一个断点并让它等待超过五分钟时,我期待一个 TimeoutException。但那并没有发生。另外,我是否需要将这两个语句放在同步块中。 Future futureResponse = service.submit(new RetrieveDoc()); //这只会阻塞 150 毫秒 String response = futureResponse.get(150, TimeUnit.MILLISECONDS);
    • @nevin 这在调试中不起作用。不,这不需要进入同步块。
    • 当时我还是有疑问,所以当时没有接受。我现在已经接受了,但我仍然不确定。如果一个线程来到这个语句 Future futureResponse = service.submit(new RetrieveDoc());然后它暂停并且其他一些线程开始在该过滤器上运行。因此,下次当该线程有机会调用 futureResponse.get 时,它将不必要地获得超时异常。
    • @nevin 对不起,我不明白你的意思。如果 ThreadA 提交了任务,它将继续执行下一行代码,它提交的任务由线程池中的一个线程执行。例如“主”线程调用 service.submit(SomeCallable)。而已! Main 不会执行任务。其他一些线程将 -> 来自您创建的 ExecutorService 的一个,它在后端有一个线程池。
    • 我想我明白了你所说的。我放置了一些记录器,发现主线程正在等待来自futureResponse.get的响应。这违背了我的目的。我希望主线程继续运行,另一个线程运行 150 毫秒并自行停止/过期。
    猜你喜欢
    • 2011-11-16
    • 2015-02-28
    • 2012-11-21
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    相关资源
    最近更新 更多