Are ThreadLocals Started in an Async-Supported Filter Thread Safe

in JSR 315 async-support for servlets and filters was added. Is a ThreadLocal created in such filter thread safe?

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

A 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() {}

}

and the relevant part of the util. I am maintaining multiple hibernate sessions within this. without getting into detail this is in support of an application level sharding solution. multiple datasources sharing entities loaded under separate class loaders... managed by different session factories.

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);
}}

i think the part i'm really asking about is Servlet 3.0 spec 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

Answers


Async architecture is no different to sync in terms of whether a ThreadLocal is threadsafe or not ie. as long as references are not leaked to other threads then it's safe.

In your snippet, ie. assume (I cannot tell) that the implementation of ThreadLocalUtil is not doing anything dangerous.

BTW - There are some limitations in several containers for running filter chain in async mode - see this on Github


Need Your Help

Mobile Vision in small view

android surfaceview barcode

I need to set Mobile Vision barcode scanner with camera preview in small SurfaceView (1/4 of screen height). How to do it proportionally, without shrinking the camera preview?

Working with Java & SQL

java mysql sql jdbc

I have been playing around with JDBC drivers. I would like some advice from the experience code masters out there. I was wondering if this is a good way to find if am connected to a database. If it...