Threading stories: ThreadLocal in web applications

This week I spend reasonable time to eliminate all our ThreadLocal variables in our web applications. The reason was that they created classloader leaks and we coudn‘t undeploy our applications properly anymore. Classloader leaks happen when a GC root keeps referencing an application object after the application was undeployed. If an application object is still referenced after undeploy, then the whole class loader can‘t be garbage collected cause the considered object references your applications class file which in turn references the classloader. This will cause an OutOfMemoryError after you‘ve undeployed and redeployed a couple of times.

ThreadLocal is one classic candidate that can easily create classloader leaks in web applications. The server is managing its threads in a pool. These threads live longer then your web application. In fact they don‘t die at all until the underlying JVM dies. Now, if you put a ThreadLocal in a pooled thread that references an object of your class you *must* be careful. You need to make sure that this variable is removed again using ThreadLocal.remove(). The issue in web applications is: where is the right place to safely remove ThreadLocal variables? Also, you may not want to modify that "removing code" every time a colleague decided to add another ThreadLocal to the managed threads.

We‘ve developed a wrapper class around thread local that keeps all the thread local variables in one single ThreadLocal variable. Here is the code.

public class ThreadLocalUtil {

    private final static ThreadLocal<ThreadVariables> THREAD_VARIABLES = new ThreadLocal<ThreadVariables>() {

        /**
         * @see java.lang.ThreadLocal#initialValue()
         */
        @Override
        protected ThreadVariables initialValue() {
            return new ThreadVariables();
        }
    };

    public static Object getThreadVariable(String name) {
        return THREAD_VARIABLES.get().get(name);
    }

    public static Object getThreadVariable(String name, InitialValue initialValue) {
        Object o = THREAD_VARIABLES.get().get(name);
        if (o == null) {
            THREAD_VARIABLES.get().put(name, initialValue.create());
            return getThreadVariable(name);
        } else {
            return o;
        }
    }

    public static void setThreadVariable(String name, Object value) {
        THREAD_VARIABLES.get().put(name, value);
    }

    public static void destroy() {
        THREAD_VARIABLES.remove();
    }
}

public class ThreadVariables extends HashMap<String, Object> { }

public abstract class InitialValue {

    public abstract Object create();

}

The advantage of the utility class is that no developer needs to manage the thread local variable lifecycle individually. The class puts all the thread locals in one map of variables. The destroy() method can be invoked where you can safely remove all thread locals in your web application. In our case thats aServletRequestListener -> requestDestroyed() method. You will also need to place finally blocks elsewhere. Typical places are near the HttpServlet, in the init()doPost()doGet() methods. This may remove all thread locals in the pooled worker threads after the request is done or an exception is thrown unexpectedly. Sometimes it happens that the main thread of the server leaks thread local variables. If that is the case you need to find the right places where to call the ThreadLocalUtil -> destroy() method. To do that figure out where the main thread actually *creates* the thread variables. You could use your debugger to do that.

Many guys out there suggest to ommit ThreadLocal in web applications for several reasons. It can be very difficult to remove them in a pooled thread environment so that you can undeploy the applications safely. ThreadLocal variables can be useful, but it‘s fair to consider other techniques before applying them. An alternative for web applications to carry request scope parameters is the HttpServletRequest. Many web frameworks allow for generic request parameter access as well as request/session attribute access, without ties to the native Servlet/Portlet API. Also many framework support request scoped beans to be injected into an object tree using dependency injection. All these options fulfill most requirements and should be considered prior to using ThreadLocal.

时间: 2024-10-12 13:45:53

Threading stories: ThreadLocal in web applications的相关文章

Ajax: A New Approach to Web Applications

Ajax: 开发web应用的新方法 by Jesse James Garrett February 18, 2005 原文网址:http://adaptivepath.com/ideas/essays/archives/000385.php 阅读这篇首创 Ajax 这个术语的文章.这是所有 Ajax 开发人员的必读文章. —————————————————————————————————————————————————— If anything about current interaction

OpenXava ------ an Rapid Development of Enterprise Web Applications.

OpenXava is an AJAX Java Framework for Rapid Development of Enterprise Web Applications. http://www.openxava.org/web/guest/home OpenXava ------ an Rapid Development of Enterprise Web Applications.,布布扣,bubuko.com

OWASP Broken Web Applications Project

找个靶机练练手 http://sourceforge.net/projects/owaspbwa/ Description Open Web Application Security Project (OWASP) Broken Web Applications Project, a collection of vulnerable web applications that is distributed on a Virtual Machine in VMware format compati

Spark - A tiny Sinatra inspired framework for creating web applications in Java 8 with minimal effor

Spark - A tiny Sinatra inspired framework for creating web applications in Java 8 with minimal effort Quick start import static spark.Spark.*; public class HelloWorld { public static void main(String[] args) { get("/hello", (req, res) -> &quo

Model-View-Controller(MVC) is an architectural pattern that frequently used in web applications. Which of the following statement(s) is(are) correct?

Model-View-Controller(MVC) is an architectural pattern that frequently used in web applications. Which of the following statement(s) is(are) correct?(多选) A.Models often represent data and the business logics needed to manipulate the data in the appli

The Tangled Web: A Guide to Securing Modern Web Applications 原版pdf

下载地址:网盘下载 内容简介 "Thorough and comprehensive coverage from one of the foremost experts in browser security." -Tavis Ormandy, Google Inc.Modern web applications are built on a tangle of technologies that have been developed over time and then hapha

SpringBoot(五) Web Applications: MVC

统一异常处理 文档: 28.1.11 Error Handling 参考 文档: 28. Developing Web Applications Spring Boot中Web应用的统一异常处理 原文地址:https://www.cnblogs.com/52liming/p/10204583.html

OAuth:Access to shared resources via web applications

A web application which wants to gain access to shared resources should redirect the user to a page of the authorization server. When doing so, it informs the authorization server about the access rights it is requesting. This information, which is c

[Cypress] install, configure, and script Cypress for JavaScript web applications -- part3

Use custom Cypress command for reusable assertions We’re duplicating quite a few commands between the registration and login of our user for assertions. Let’s see how we can take these assertions and create a custom command to make the assertions. We