论坛首页 Java企业应用论坛

spring的DispatcherServlet不是线程安全的.

浏览 3343 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2016-01-09  
大概看了一下tomcat实例化servlet的源代码,和spring mvc的DispatcherServlet的源代码,现在问题来了,spring的DispatcherServlet不是线程安全的.

我看的源代码版本是:tomcat 7.0.57 spring 3.0.5. 重点查看了org.apache.catalina.core.StandardWrapper和DispatcherServlet的源代码。

为什么说DispatcherServlet不是线程安全(有可能不可见)现在问题如下:

StandardWrapper是Servlet的包装类,其内有个protected volatile Servlet instance = null;属性,存放的servlet的实例,这个实例使用标准的双检查锁来实例化和初始化,初始化的时候在synchronized(this)的同步块内,调用 servlet.init(facade);因为在synchronized同步块内,其可以保证在同步块结束后所有对成员变量的修改都会刷新(写回)到主内存。

说到上面的servlet.init(facade);我们现在来切换到DispatcherServlet类,这个类继承于FrameworkServlet -> HttpServletBean -> HttpServlet,DispatcherServlet的initStrategies(ApplicationContext context),也是在servlet.init(facade)方法内的调用,因此也在synchronzied同步块内调用,因此其可以保证initStrategies方法对DispatcherServlet实例成员变量的修改后刷新到主内存。

我们再来看看DispatcherServlet的一些成员变量的声明,都是普通的声明,前都没有用final和volatile修饰:

/** MultipartResolver used by this servlet */
private MultipartResolver multipartResolver;

/** LocaleResolver used by this servlet */
private LocaleResolver localeResolver;

/** ThemeResolver used by this servlet */
private ThemeResolver themeResolver;

/** List of HandlerMappings used by this servlet */
private List handlerMappings;

/** List of HandlerAdapters used by this servlet */
private List handlerAdapters;

/** List of HandlerExceptionResolvers used by this servlet */
private List handlerExceptionResolvers;

/** RequestToViewNameTranslator used by this servlet */
private RequestToViewNameTranslator viewNameTranslator;

/** FlashMapManager used by this servlet */
private FlashMapManager flashMapManager;

/** List of ViewResolvers used by this servlet */
private List viewResolvers;

现在就要问题的实质了,doDispatch(HttpServletRequest request, HttpServletResponse response)方法,在没有任何同步的情况下,使用上面这些属性的实例,可见性能保证吗?
   发表时间:2016-01-11  
没看过源码,从字段名上来看这些成员字段只是一些初始化后就不会改变的信息吧,也就是说后面都是只读的操作,不会存在线程安全的问题。
都是一些处理器和一些配置信息,映射信息等,这些在运行期间不会改变,只要初始化时安全就行。

只要运行期间无状态的改变,或者这个类自身是无状态的,就不存在线程安全的问题。
0 请登录后投票
   发表时间:2016-01-15  
永恒的蓝色信念 写道
没看过源码,从字段名上来看这些成员字段只是一些初始化后就不会改变的信息吧,也就是说后面都是只读的操作,不会存在线程安全的问题。
都是一些处理器和一些配置信息,映射信息等,这些在运行期间不会改变,只要初始化时安全就行。

只要运行期间无状态的改变,或者这个类自身是无状态的,就不存在线程安全的问题。


不可变,就能保证可见性吗,这两个不是一个概念。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics