我在看《Servlet与JSP核心编程》时,文中在介绍基于ServletContext的RequestDispatcher的时候需要同步,我一直没有想明白什么场景有问题,为什么在this上同步。相关代码如下:
synchronized{
    ValueObject value = new valueObject();
    getServletContext().setAttribute("key", value);
    RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/Somepage.jsp");
    dispatcher.forward(request, response);
}

解决方案 »

  1.   

    这句不是在读文件吧,一个请求一个线程的话,有可能多个请求同时要转发,而/WEB-INF/Somepage.jsp只能同时被一个线程访问。
      

  2.   

    你的意思是担心多个线程同时读/WEB-INF/Somepage.jsp? 
    我还有个疑问,一般来说Application Server在第一个请求过来的时候会将Somepage.jsp编译成servlet,然后load到内存中,以后其他请求过来的时候就不需要再次读文件了。就算几乎同时两个初始请求过来导致Application Server读Somepage.jsp,这个时候Application Server应该自己同步的。否则岂不是所有的jsp都要被同步保护起来吗?
      

  3.   

    ValueObject value = new valueObject();
    getServletContext().setAttribute("key", value);这里需要同步,因该是
      

  4.   

    应该不是下面需要同步,因为ServletContext自己已经做了同步,不需要调用进程对其进行同步ValueObject value = new valueObject();
    getServletContext().setAttribute("key", value);
      

  5.   

    嗯   
    Servlet中ServletContext与HttpSession在用setAttribute时都要同步
    可能出现
        线程一调用ServletContext.setAttribute("a", "aaa");
        线程二调用ServletContext.setAttribute("a", "bbb");
        线程一转到JSP页面调用ServletContext.getAttribute("a");
            这时打印的是bbb
        线程二转到JSP页面调用ServletContext.getAttribute("a");
            这时打印的是bbb
      

  6.   


    我自己没有权限修改帖子,书中写的是synchronized(this),也就是说是用该Servlet的锁进行同步。所以这个是没有办法阻止其他Servlet的线程访问ServletContext的,因此这个解释还是不对
      

  7.   

    基于ServletContext的RequestDispatcher的时候需要同步ServletContext是针对整个应用来跳的。可能A跳到 a.jsp页面去
    而B操作跳到 b.jsp去可能会影响A的结果如果不加锁肯能会跳错,看是不是这样
      

  8.   

    请看我上面的回复,用synchrnozized(this)只能控制由该servlet拉起的线程,根本阻止不了其他的servlet拉起的线程
      

  9.   

    这不叫 基于ServletContext的RequestDispatcher ,在程序中实质上servletContext与dispatcher没有太大的关系,只不过在servletContext中保存了参数而已,在实际的开发中,很少会将参数保存到servletContext中,你不必纠结这个,我想之所以同步应该就是这参数原因,servletContext范围在环境中是最大的,每个用户都可对这个参数进行修改,所以要同步,不过这样做会有问题