Java Servlet doGet同步-不';不行?

Java Servlet doGet同步-不';不行?,java,multithreading,servlets,synchronized,Java,Multithreading,Servlets,Synchronized,我知道这是一个简单的问题,但不知何故我感到困惑 若我理解得很好,简单地说,当请求到达web服务器时,他会为每个请求创建一个线程到某个servlet 假设我们在MyServlet中有下一个代码(我省略了异常处理和类似的代码): 我希望这个servlet会被卡住,因为进入这个方法的第一个线程(param=a)将永远保持等待状态,因为任何其他未来的线程都会因为synchronized关键字而被卡住在doGet前面,并且由于这个原因,notifyAll永远不会被执行 现在,如果我在浏览器中打开新选项卡并

我知道这是一个简单的问题,但不知何故我感到困惑

若我理解得很好,简单地说,当请求到达web服务器时,他会为每个请求创建一个线程到某个servlet

假设我们在MyServlet中有下一个代码(我省略了异常处理和类似的代码):

我希望这个servlet会被卡住,因为进入这个方法的第一个线程(param=a)将永远保持等待状态,因为任何其他未来的线程都会因为synchronized关键字而被卡住在doGet前面,并且由于这个原因,notifyAll永远不会被执行

现在,如果我在浏览器中打开新选项卡并点击/MyServlet?p=a,浏览器将等待127.0.0.1。。。 之后,我打开新标签并点击/MyServlet?p=b(或任何是!=a的东西),第一个标签被释放并打印出“Hello!”消息

这意味着第二个线程已经进入doGet,并执行notifyAll

为什么会这样?我错过了什么?

因为
wait()
通过输入
synchronized
块释放它以前获得的锁。从对象的javadoc。等待:

线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后线程等待,直到它可以重新获得监视器的所有权并恢复执行

因此,您的第一个请求获得锁,进入
doGet
方法,并调用
wait
(释放锁并等待)。第二个请求获得锁,进入
doGet
,并调用
notifyAll
,这将唤醒第一个请求的线程


在使用这些方法之前,请仔细阅读
wait
notify
/
notifyAll
等方法的文档,这一点至关重要,否则您会遇到麻烦。

非常感谢您的回答
synchronized protected void doGet( ... ...){
    PrintWritet pw=response.getWriter();
    String param=request.getParameter("p");

    if(param.equals("a")){
        wait();
    }else{
        notifyAll();
    }

    pw.write("Hello!");
}