[英]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.