spring的DispatcherServlet不是线程安全的.

大概看了一下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)方法,在没有任何同步的情况下,使用上面这些属性的实例,可见性能保证吗?

猜你喜欢

转载自neptune.iteye.com/blog/2269533
今日推荐