When and how should I use a ThreadLocal variable?

前端 未结 25 1892
再見小時候
再見小時候 2020-11-22 12:35

When should I use a ThreadLocal variable?

How is it used?

相关标签:
25条回答
  • 2020-11-22 13:10
    1. ThreadLocal in Java had been introduced on JDK 1.2 but was later generified in JDK 1.5 to introduce type safety on ThreadLocal variable.

    2. ThreadLocal can be associated with Thread scope, all the code which is executed by Thread has access to ThreadLocal variables but two thread can not see each others ThreadLocal variable.

    3. Each thread holds an exclusive copy of ThreadLocal variable which becomes eligible to Garbage collection after thread finished or died, normally or due to any Exception, Given those ThreadLocal variable doesn't have any other live references.

    4. ThreadLocal variables in Java are generally private static fields in Classes and maintain its state inside Thread.

    Read more: ThreadLocal in Java - Example Program and Tutorial

    0 讨论(0)
  • 2020-11-22 13:14

    Nothing really new here, but I discovered today that ThreadLocal is very useful when using Bean Validation in a web application. Validation messages are localized, but by default use Locale.getDefault(). You can configure the Validator with a different MessageInterpolator, but there's no way to specify the Locale when you call validate. So you could create a static ThreadLocal<Locale> (or better yet, a general container with other things you might need to be ThreadLocal and then have your custom MessageInterpolator pick the Locale from that. Next step is to write a ServletFilter which uses a session value or request.getLocale() to pick the locale and store it in your ThreadLocal reference.

    0 讨论(0)
  • 2020-11-22 13:14

    There are 3 scenarios for using a class helper like SimpleDateFormat in multithread code, which best one is use ThreadLocal

    Scenarios

    1- Using like share object by the help of lock or synchronization mechanism which makes the app slow

    2- Using as a local object inside a method

    In this scenario, if we have 4 thread each one calls a method 1000 time then we have
    4000 SimpleDateFormat object created and waiting for GC to erase them

    3- Using ThreadLocal

    if we have 4 thread and we gave to each thread one SimpleDateFormat instance
    so we have 4 threads, 4 objects of SimpleDateFormat.

    There is no need of lock mechanism and object creation and destruction. (Good time complexity and space complexity)

    0 讨论(0)
  • 2020-11-22 13:15

    Since Java 8 release, there is more declarative way to initialize ThreadLocal:

    ThreadLocal<Cipher> local = ThreadLocal.withInitial(() -> "init value");
    

    Until Java 8 release you had to do the following:

    ThreadLocal<String> local = new ThreadLocal<String>(){
        @Override
        protected String initialValue() {
            return "init value";
        }
    };
    

    Moreover, if instantiation method (constructor, factory method) of class that is used for ThreadLocal does not take any parameters, you can simply use method references (introduced in Java 8):

    class NotThreadSafe {
        // no parameters
        public NotThreadSafe(){}
    }
    
    ThreadLocal<NotThreadSafe> container = ThreadLocal.withInitial(NotThreadSafe::new);
    

    Note: Evaluation is lazy since you are passing java.util.function.Supplier lambda that is evaluated only when ThreadLocal#get is called but value was not previously evaluated.

    0 讨论(0)
  • 2020-11-22 13:16

    Many frameworks use ThreadLocals to maintain some context related to the current thread. For example when the current transaction is stored in a ThreadLocal, you don't need to pass it as a parameter through every method call, in case someone down the stack needs access to it. Web applications might store information about the current request and session in a ThreadLocal, so that the application has easy access to them. With Guice you can use ThreadLocals when implementing custom scopes for the injected objects (Guice's default servlet scopes most probably use them as well).

    ThreadLocals are one sort of global variables (although slightly less evil because they are restricted to one thread), so you should be careful when using them to avoid unwanted side-effects and memory leaks. Design your APIs so that the ThreadLocal values will always be automatically cleared when they are not needed anymore and that incorrect use of the API won't be possible (for example like this). ThreadLocals can be used to make the code cleaner, and in some rare cases they are the only way to make something work (my current project had two such cases; they are documented here under "Static Fields and Global Variables").

    0 讨论(0)
  • 2020-11-22 13:16

    There is very good example in book Java Concurrency in Practice. Where author (Joshua Bloch) explains how Thread confinement is one of the simplest ways to achieve thread safety and ThreadLocal is more formal means of maintaining thread confinement. In the end he also explain how people can abuse it by using it as global variables.

    I have copied the text from the mentioned book but code 3.10 is missing as it is not much important to understand where ThreadLocal should be use.

    Thread-local variables are often used to prevent sharing in designs based on mutable Singletons or global variables. For example, a single-threaded application might maintain a global database connection that is initialized at startup to avoid having to pass a Connection to every method. Since JDBC connections may not be thread-safe, a multithreaded application that uses a global connection without additional coordination is not thread-safe either. By using a ThreadLocal to store the JDBC connection, as in ConnectionHolder in Listing 3.10, each thread will have its own connection.

    ThreadLocal is widely used in implementing application frameworks. For example, J2EE containers associate a transaction context with an executing thread for the duration of an EJB call. This is easily implemented using a static Thread-Local holding the transaction context: when framework code needs to determine what transaction is currently running, it fetches the transaction context from this ThreadLocal. This is convenient in that it reduces the need to pass execution context information into every method, but couples any code that uses this mechanism to the framework.

    It is easy to abuse ThreadLocal by treating its thread confinement property as a license to use global variables or as a means of creating “hidden” method arguments. Like global variables, thread-local variables can detract from reusability and introduce hidden couplings among classes, and should therefore be used with care.

    0 讨论(0)
提交回复
热议问题