繁体   English   中英

Servlet是否适合复合操作?

[英]Are Servlets suitable for composite operations?

Servlet是非线程安全的,状态可能会因不同请求而在方法调用之间丢失。

但是我可以在单个请求期间安全地在自己的Servlet方法之间保持状态以实现复合操作吗?

像这样:

public class MyServlet extends HttpServletRequest {

    private String var;

    void addH() {
        var += "h";
    }

    void addI() {
        var += "i";
    }

    void doGet(...) {
        addH();
        addI();
        // var = "hi"?
    }
}

在这种情况下,即使并发请求, var也会包含正确的值吗? 换句话说,它像EJB中的无状态Bean一样工作吗?

public class MyServlet extends HttpServletRequest {

    private String var = "";

    void addH() {
        var += "h";
    }

    void addI(long dontAnswerBefore) {
        while(System.currentTimeMillis() < dontAnswerBefore) {
          // Do nothing 
        }
        var += "i";
    }

    void doGet(...) {
        long now = System.currentTimeMillis();
        addH();
        addI(now + 10_000);
        resp.write(var);
    }
}

这将使您有10秒的时间在两个选项卡或两个不同的浏览器中发出两个请求。

不,你不能。 就像您说的那样,servlet不是线程安全的。 一个请求不存在受保护的“空间”。因此,多个线程(以及多个请求)可以同时命中var 如果您想要这样一个受保护的“空间”,则需要同步doGet() (这当然会破坏并发性)或执行类似使用ThreadLocal以便每个线程(并因此获得请求)拥有自己的实例范围的单独副本。州。

如果不需要状态在请求之外持久化,则可以在doGet()创建状态并将其传递给其他方法:

void doGet(...) {
    StringBuilder var = new StringBuilder();
    addH(var);
    addI(var);
    resp.write(var.toString());
}

void addH(StringBuilder var) {
    var.append('h');
}

void addI(StringBuilder var) {
    ver.append('i');
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM