ThreadLocals 是否在支持异步的线程安全的过滤器中启动
Are ThreadLocals Started in an Async-Supported Filter Thread Safe
在 JSR 315 中添加了对 servlet 和过滤器的异步支持。在这样的过滤器线程中创建的 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() {}
}
和实用程序的相关部分。我在其中维护多个休眠会话。无需详细说明,这是为了支持应用程序级分片解决方案。多个数据源共享在单独的 class 加载器下加载的实体...由不同的会话工厂管理。
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.4
http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf?AuthParam=1455121502_a9b513ab9b8fc5ac5a82d0518e88f7ac
就 ThreadLocal 是否线程安全而言,异步架构与同步架构没有什么不同,即。只要引用没有泄露给其他线程就安全了。
在您的代码段中,即。假设(我不能说) ThreadLocalUtil
的实施没有做任何危险的事情。
顺便说一句 - 在异步模式下 运行 过滤器链的几个容器有一些限制 - 请参阅 this on Github
在 JSR 315 中添加了对 servlet 和过滤器的异步支持。在这样的过滤器线程中创建的 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() {}
}
和实用程序的相关部分。我在其中维护多个休眠会话。无需详细说明,这是为了支持应用程序级分片解决方案。多个数据源共享在单独的 class 加载器下加载的实体...由不同的会话工厂管理。
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.4 http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-eval-oth-JSpec/servlet-3_0-final-spec.pdf?AuthParam=1455121502_a9b513ab9b8fc5ac5a82d0518e88f7ac
就 ThreadLocal 是否线程安全而言,异步架构与同步架构没有什么不同,即。只要引用没有泄露给其他线程就安全了。
在您的代码段中,即。假设(我不能说) ThreadLocalUtil
的实施没有做任何危险的事情。
顺便说一句 - 在异步模式下 运行 过滤器链的几个容器有一些限制 - 请参阅 this on Github