[英]Servlet doGet synchronization - doesn't work?
我知道这是一个简单的问题,但我有些困惑。
如果我理解得很好,简单来说,当请求到达Web服务器时,他会为每个请求创建一个线程给某个servlet。
考虑到我们在MyServlet中有下一个代码(我遗漏了异常处理和类似的代码):
synchronized protected void doGet( ... ...){
PrintWritet pw=response.getWriter();
String param=request.getParameter("p");
if(param.equals("a")){
wait();
}else{
notifyAll();
}
pw.write("Hello!");
}
我希望这个servlet会卡住,因为进入这个方法的第一个线程(带有param = a)将永远等待,因为任何其他未来的线程都会因为synchronized关键字而停留在doGet前面,并且因为那个notifyAll将永远不会得到执行。
现在,如果我在浏览器中打开新选项卡并点击/ MyServlet?p = a,浏览器等待127.0.0.1 ...之后,我打开新标签并点击/ MyServlet?p = b(或任何东西!= a )第一个标签发布并打印出“你好!” 信息。
这意味着第二个线程已进入doGet,并执行notifyAll。
为什么会这样? 我错过了什么?
因为wait()
通过输入synchronized
块释放先前获得的锁。 从Object.wait
的javadoc:
线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
因此,您的第一个请求获取锁定,输入doGet
方法,并调用wait
(释放锁定并等待)。 第二个请求获取锁,输入doGet
,并调用notifyAll
,它唤醒第一个请求的线程。
在您使用它们之前仔细阅读wait
和notify
/ notifyAll
wait
方法的文档是非常重要的 ,否则您将遇到麻烦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.