java - 这是缓存关闭线程保存吗?

标签 java servlets closures

public class ExampleServlet extends HttpServlet{

    private Closure closure;

    @Override
    protected void doPost(final HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Do some stuff here...
        if (this.closure == null){
            this.closure = new Closure(){
                @Override
                public void someFunction(){
                    req.getRequestURI(); // Obviously do something with it...
                }
            }
        }

        // Later...
        this.closure.someFunction(); // << Is this thread-save??

        // More stuff here...
    }
}

在示例中,我无法控制Closure!

如果我测试它,它工作正常。问题是:

是否每个请求线程都获得了闭包字段的新副本?否则,当一个新的请求进来时,引用的 req 字段会改变,而 someFunction() 仍在执行。还是通过将 req 声明为 final 来处理?

最佳答案

所有请求都使用相同的 servlet 实例。

因此闭包将只为第一个请求创建并在所有后续请求之间共享。

它将继续引用命中 servlet 的初始请求,因此这根本不起作用,即使没有多线程(单线程顺序请求也被破坏)。

如果您确实有多个线程,您会遇到额外的复杂情况,例如必须在 servlet 实例上为“惰性单例初始化”部分进行同步。理想情况下,所有此类初始化都在 servlet 的 init 方法中完成。

你不能把它设为 doPost 中的局部变量吗?

Does every request-thread get a new copy of the closure-field?

没有。它们都共享同一个 servlet,带有(单个)闭包字段。

when a new request comes in, the referenced req-field would change while the someFunction() is still executing.

没有。捕获的 req 在闭包的生命周期内不会改变。它是 final 并在首次创建闭包时从 servlet 复制而来。它将继续引用命中 servlet 的第一个请求。

Or is this handled by declaring req as final?

由于 how closures in Java are implemented 的性质,这是一项技术要求.它们并不真正捕获变量,它们捕获变量的快照值作为副本。

关于java - 这是缓存关闭线程保存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27326953/

相关文章:

javascript - javascript 对象的值不变(通过引用传递)

java - 从 xsl 读取字符串时如何摆脱 '\n' 字符?

java - Primefaces fileDownload - 已经为此响应调用了 getOutputStream()

java - 如何支持变量上下文路径?

java - 重定向到java中的另一个servlet

java - netbeans 中最简单的 servlet 和 web.xml

引用外部对象的 Javascript 作用域

java - 如何在运行时获取设备高度和宽度?

java - 应用程序无法启动

function - 'closure' 和 'lambda' 之间有什么区别?