线程局部变量是否在异步支持的筛选器线程安全中启动



在JSR 315中添加了对servlets和过滤器的异步支持。在此类过滤器线程中创建的 ThreadLocal 是否安全?

<filter>
    <filter-name>ResourceFilter</filter-name>
    <filter-class>com.app.filter.ResourceFilter</filter-class>
    <async-supported>true</async-supported>
</filter>

一个过滤器

public class ResourceFilter implements Filter  {

private final Logger log = LoggerFactory.getLogger(getClass());
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    try{
        String uri = WebUtilityHelper.getURI(request);
        boolean isAResource = WebUtilityHelper.isAResource(uri);
        ThreadLocalUtil.setIsResource(isAResource);
        log.trace("URI: {}, isAResource? {}", uri, isAResource);
    } finally {         
        chain.doFilter(request, response);
    }
}
@Override
public void destroy() {}

}

以及实用程序的相关部分。我在其中维护多个休眠会话。无需详细介绍,这是为了支持应用程序级分片解决方案。多个数据源共享在单独的类装入器下加载的实体...由不同的会话工厂管理。

public class ThreadLocalUtil {
/* Contant static names */
private static final String HIBERNATE_ASYNC_SESSION = "hibernateAsyncSession";
private static final String HIBERNATE_GLOBAL_SESSION = "hibernateGlobalSession";

private static final String IS_RESOURCE = "isResource";
/* The Constant THREAD_VARIABLES */
private static final ThreadLocal<ThreadVariables> THREAD_VARIABLES = new ThreadLocal<ThreadVariables>() {
    /**
     * @see java.lang.ThreadLocal#initialValue()
     */
    @Override
    protected ThreadVariables initialValue() {
        return new ThreadVariables();
    }
};

public static Object get(String name) {
    return getThreadVariable(name);
}
/**
 * Gets the thread variable.
 *
 * @param name
 *            the name
 * @return the thread variable
 */
public static Object getThreadVariable(String name) {
    return THREAD_VARIABLES.get().get(name);
}    /**
 * Sets the thread variable.
 *
 * @param name
 *            the name
 * @param value
 *            the value
 */
public static synchronized void setThreadVariable(String name,
        Object value) {
    THREAD_VARIABLES.get().put(name, value);
}
/**
 * Destroy.
 */
public static void destroy() {
    closeAllHibernateSessions();
    THREAD_VARIABLES.remove();
}
public static void remove(String name) {
    THREAD_VARIABLES.get().remove(name);
}}

我认为我真正要问的部分是Servlet 3.0 规范 2.3.3.4http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf?AuthParam=1455121502_a9b513ab9b8fc5ac5a82d0518e88f7ac

异步架构与同步没有什么不同,即 ThreadLocal 是否线程安全。 只要引用不泄漏到其他线程,那么它就是安全的。

在您的片段中,即假设(我无法判断)ThreadLocalUtil的实现没有做任何危险的事情。

顺便说一句 - 在异步模式下运行过滤器链的几个容器中存在一些限制 - 在 Github 上看到这个

最新更新