【问题标题】:Simultaneously processing in one Servlet在一个 Servlet 中同时处理
【发布时间】:2014-09-18 20:13:30
【问题描述】:

我有一个接收请求的 Servlet,必须处理 5 个任务(从外部服务器获取数据)并将所有数据发送回订购的客户端。

如何同时处理5个Task,5个Task全部完成后继续Servlet代码?

【问题讨论】:

    标签: java multithreading servlets asynchronous


    【解决方案1】:

    您可以使用CoundDownLatch

    一种同步辅助,它允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。

    示例代码:

        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal = new CountDownLatch(5); // 5 tasks
    
        class Worker implements Runnable {
            private final CountDownLatch startSignal;
            private final CountDownLatch doneSignal;
            private final int threadNumber;
    
            // you can pass additional arguments as well
            Worker(CountDownLatch startSignal, CountDownLatch doneSignal,
                                                       int threadNumber) {
                this.startSignal = startSignal;
                this.doneSignal = doneSignal;
                this.threadNumber = threadNumber;
            }
    
            public void run() {
                try {
                    startSignal.await();
                    doWork(); // actual work to be performed here    
                    doneSignal.countDown();
                } catch (InterruptedException ex) {
                    LOGGER.error(ex);
                }
            }
        }
    
        // 5 new threads are started
        for(int i=1;i<=5;i++){
            new Thread(new Worker(startSignal, doneSignal, i)).start();
        }
    
        startSignal.countDown(); // let all threads proceed
        try {
            doneSignal.await(); // wait for all to finish
            // all 5 tasks are finished and do whatever you want to do next
        } catch (InterruptedException interruptedException) {
            LOGGER.error(interruptedException);
        }
    

    Read more...Find more examples...

    【讨论】:

    • 谢谢,这是一个很好的解决方案。但是在您的示例中,我只是在 5 个线程中启动相同的任务(此处:doWork())5 次。如何开始 5 个不同的任务?
    • 在代码中我已经启动了 5 个线程。只需检查 worker 类中的 threadNumber 并根据该数字执行。
    【解决方案2】:

    另一个选项是ExecutorService。有多种示例可供选择,包括:

    以下是从上面找到的第一个链接中获取的一些示例代码:

    ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
    while(...) {
      taskExecutor.execute(new MyTask());
    }
    taskExecutor.shutdown();
    try {
      taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    } catch (InterruptedException e) {
      ...
    }
    

    【讨论】:

    • 你在集群环境下测试过Servlet吗?
    • @user3218114 您最初的问题没有提到任何关于集群环境的内容。这只是一些示例代码和参考,可帮助您入门。您必须尝试一下,看看这是否符合您的要求。
    • 我不是 OP。我在实时应用程序中使用了 CountDownLatch,之后我将其作为答案分享。我只是问。不用担心。
    • @user3218114 对,对不起。你的用户名让我很困惑。它与 OP 非常相似。你需要一个独特的哈哈!我在实时应用程序中使用了ExecutorService,但它不在集群环境中。但我相信它在Java中被广泛使用。
    • yes Sid 如果您查看我之前的编辑然后我建议使用 ExecutorService 然后我没有测试它因此我再次编辑了我的帖子。
    【解决方案3】:

    5秒太长了,可能会占用web服务器资源,你可以让客户端发送一个请求A,触发你的5秒任务,但它不等待,立即返回。既然你知道将需要 5 秒,您可以在 5 秒后发送另一个请求 B,以获取数据。如果数据还没有准备好,您可以再过 5 秒再请求,直到达到 MAX_RETRY_COUNT(由您自己定义)。

    【讨论】:

      猜你喜欢
      • 2019-02-28
      • 2016-08-21
      • 2014-04-12
      • 2011-05-12
      • 2013-03-08
      • 2014-07-29
      • 2021-05-01
      • 2012-02-03
      • 2012-11-06
      相关资源
      最近更新 更多