Java Multithreading 10: The Role and Use of ThreadLocal

From: http://www.cnblogs.com/xrq730/p/4854820.html


The role of ThreadLocal

From the analysis of ThreadLocal in the previous article, it can be concluded that ThreadLocal is not used to solve the problem of multi-threaded access to shared objects. It is the thread itself that is set to the thread's ThreadLocal.ThreadLocalMap through the set() method of ThreadLocal. The object to be stored does not need to be accessed by other threads and cannot be accessed. The values ​​in ThreadLocal.ThreadLocalMap and ThreadLocal.ThreadLocal in each thread are different objects.

As for why you should use ThreadLocal, consider this question in this way. In Java Web, write a servlet:

copy code
public class Servlet extends HttpServlet
{

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        this.doGet(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        
    }
}
copy code

I want to get this HttpServletRequest in a normal JavaBean, but I can't pass the parameters:

copy code
public class OperateRequest
{
    public String operateRequest()
    {
        return null;
    }
}
copy code

What should we do at this time? The first solution is to define a global HttpServletRequest in the Servlet class. As for how to define it, it can be defined as static, or it can be defined as non-static but provides setter/getter externally, and then the operateRequest() method is called every time. Just take this global HttpServletRequest.

Admittedly, this is a viable solution, but this solution has one big drawback: competition. Since HttpServletRequest is global, it is necessary to introduce a synchronization mechanism to ensure thread safety. The introduction of a synchronization mechanism means sacrificing the time for responding to users-this is unbearable in the Java Web that focuses on responding to users.

所以,我们引入ThreadLocal,既然ThreadLocal.ThreadLocalMap是线程独有的,别的线程访问不了也没必要访问,那我们通过ThreadLocal把HttpServletRequest设置到线程的ThreadLocal.ThreadLocalMap里面去不就好了?这样,在一次请求中哪里需要用到HttpServletRequest,就使用ThreadLocal的get()方法就把这个HttpServletRequest给取出来了,是不是一个很好的解决方案呢?

 

ThreadLocal使用

忘记上面那个复杂的问题,我们来看一下ThreadLocal的简单使用,首先ThreadLocal肯定是全局共享的:

public class Tools
{
    public static ThreadLocal<String> t1 = new ThreadLocal<String>();
}

写一个线程往ThreadLocal里面塞值:

copy code
public class ThreadLocalThread extends Thread
{
    private static AtomicInteger ai = new AtomicInteger();
    
    public ThreadLocalThread(String name)
    {
        super(name);
    }
    
    public void run()
    {
        try
        {
            for (int i = 0; i < 3; i++)
            {
                Tools.t1.set(ai.addAndGet(1) + "");
                System.out.println(this.getName() + " get value--->" + Tools.t1.get());
                Thread.sleep(200);
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
copy code

写个main函数,启动三个ThreadLocalThread:

copy code
public static void main(String[] args) throws Exception
    {
        ThreadLocalThread a = new ThreadLocalThread("ThreadA");
        ThreadLocalThread b = new ThreadLocalThread("ThreadB");
        ThreadLocalThread c = new ThreadLocalThread("ThreadC");
        a.start();
        b.start();
        c.start();
    }
copy code

看一下运行结果:

copy code
ThreadA get value--->1
ThreadC get value--->2
ThreadB get value--->3
ThreadB get value--->4
ThreadC get value--->6
ThreadA get value--->5
ThreadC get value--->8
ThreadA get value--->7
ThreadB get value--->9
copy code

看到每个线程的里都有自己的String,并且互不影响----因为绝对不可能出现数字重复的情况。用一个ThreadLocal也可以多次set一个数据,set仅仅表示的是线程的ThreadLocal.ThreadLocalMap中table的某一位置的value被覆盖成你最新设置的那个数据而已,对于同一个ThreadLocal对象而言,set后,table中绝不会多出一个数据

 

ThreadLocal再总结

上一篇文章的最后有对ThreadLocal的工作原理进行总结,这里对ThreadLocal再次进行一个总结:

1. ThreadLocal is not a collection . It does not store any content. The collection that really stores data is in Thread. ThreadLocal is just a tool, a tool to set a value to a certain position of the table in the ThreadLocal.ThreadLocalMap of each thread

2. Synchronization and ThreadLocal are two ideas for solving data access problems in multithreading. The former is the idea of ​​data sharing , and the latter is the idea of ​​data isolation.

3. Synchronization is the idea of ​​exchanging time for space, and ThreadLocal is the idea of ​​exchanging space for time

4. Since ThreadLocal is related to threads, for Java Web, the value set by ThreadLocal is only valid in one request. Is it similar to request? Because the content in the request is only valid for one request, compare the difference between the two:

(1) ThreadLocal can only store one value. Since a Request is in the form of a Map, multiple values ​​can be stored in the form of key-value

(2) ThreadLocal is generally used in the framework, and Request is generally used in the presentation layer, Action, Servlet


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326899653&siteId=291194637