When and how should I use a ThreadLocal variable?

2018-12-31 15:50发布

When should I use a ThreadLocal variable?

How is it used?

24条回答
像晚风撩人
2楼-- · 2018-12-31 16:42

The documentation says it very well: "each thread that accesses [a thread-local variable] (via its get or set method) has its own, independently initialized copy of the variable".

You use one when each thread must have its own copy of something. By default, data is shared between threads.

查看更多
若你有天会懂
3楼-- · 2018-12-31 16:43

when?

When an object is not thread-safe, instead of synchronization which hampers the scalability, give one object to every thread and keep it thread scope, which is ThreadLocal. One of most often used but not thread-safe objects are database Connection and JMSConnection.

How ?

One example is Spring framework uses ThreadLocal heavily for managing transactions behind the scenes by keeping these connection objects in ThreadLocal variables. At high level, when a transaction is started it gets the connection ( and disables the auto commit ) and keeps it in ThreadLocal. on further db calls it uses same connection to communicate with db. At the end, it takes the connection from ThreadLocal and commits ( or rollback ) the transaction and releases the connection.

I think log4j also uses ThreadLocal for maintaining MDC.

查看更多
人间绝色
4楼-- · 2018-12-31 16:44

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.

查看更多
闭嘴吧你
5楼-- · 2018-12-31 16:45

Threadlocal provides a very easy way to achieve objects reusability with zero cost.

I had a situation where multiple threads were creating an image of mutable cache, on each update notification.

I used a Threadlocal on each thread, and then each thread would just need to reset old image and then update it again from the cache on each update notification.

Usual reusable objects from object pools have thread safety cost associated with them, while this approach has none.

查看更多
春风洒进眼中
6楼-- · 2018-12-31 16:46

You have to be very careful with the ThreadLocal pattern. There are some major down sides like Phil mentioned, but one that wasn't mentioned is to make sure that the code that sets up the ThreadLocal context isn't "re-entrant."

Bad things can happen when the code that sets the information gets run a second or third time because information on your thread can start to mutate when you didn't expect it. So take care to make sure the ThreadLocal information hasn't been set before you set it again.

查看更多
笑指拈花
7楼-- · 2018-12-31 16:47

One possible (and common) use is when you have some object that is not thread-safe, but you want to avoid synchronizing access to that object (I'm looking at you, SimpleDateFormat). Instead, give each thread its own instance of the object.

For example:

public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}

Documentation.

查看更多
登录 后发表回答