【问题标题】:How to persist request object in a running Thread?如何在正在运行的线程中持久化请求对象?
【发布时间】:2015-12-23 02:04:48
【问题描述】:

我将 HttpServletRequest 对象传递给一个线程,然后返回它。线程将长时间执行,但在此之前我返回请求。因此我无法访问 Thread 中的 HttpServletRequest 对象。那么有没有办法在整个线程执行过程中保持 HttpServletRequest 对象,即使在完成会话之后也是如此?

 public String execute(HttpServletRequest request){
       Runnable r = new RunnableImplementation(request);
       Thread t = new Thread(r);
       t.start();
       return "Success";
    }

注意:RunnableImplementation 的构造函数初始化其本地 HttpServletRequest 对象,然后在其 run() 方法中使用。

【问题讨论】:

    标签: java multithreading scope


    【解决方案1】:

    您不太可能需要请求对象中的所有内容,因此请编写一个仅存储您需要的位的类,并将其实例传递给您的后台任务。这样做的原因是,虽然原始请求对象在请求结束时不会神奇地“消失”(只要你持有对它的强引用,它就不能被垃圾收集),但谁知道呢应用程序服务器对其字段做了什么?可能什么都没有,但它可能会将它们清空,也许它会将对象重新用于另一个请求。以上皆有可能。

    3.0 Java Servlet 规范在第 3.11 节中明确涵盖了这个主题:

    每个请求对象仅在 servlet 的范围内有效 service 方法,或在过滤器的 doFilter 方法范围内, 除非为组件启用了异步处理并且 在请求对象上调用startAsync 方法。在这种情况下 在发生异步处理的情况下,请求对象保持有效 直到在AsyncContext 上调用complete。常用容器 回收请求对象以避免性能开销 请求对象创建。开发人员必须意识到维护 对 startAsync 尚未被引用的请求对象的引用 不推荐在上述范围之外调用,因为它可能 有不确定的结果。

    并且使用 ExecutorService 而不是从 servlet 手动启动线程,因为后者对于可扩展性来说是一个非常糟糕的主意。

    【讨论】:

      【解决方案2】:

      您不需要该请求。您需要在请求中提供一些信息。

      只需从请求中提取它们并用它们构造一个对象并将其传递给您的可运行对象。

      这是一个示例代码:

      MyThreadRequest myThreadRequest = new MyThreadRequest();
      myThreadRequest.setUser((User) request.getAttribute("user"));
      Thread t = new Thread(new RunnableImplementation(myThreadRequest));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 2016-11-14
        • 1970-01-01
        相关资源
        最近更新 更多