threadLocal 原理与使用

Posted youxin2012

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了threadLocal 原理与使用相关的知识,希望对你有一定的参考价值。

目标:用于每个线程资源的隔离.

当工作于多线程中的对象使用ThreadLocal 维护变量时,ThreadLocal 为 每个使用该变量的线程分配一个独立的变量副本。每个线程独立改变自己的副本,而不影响其他线程所对应的变量副本。

不同于线程同步:线程同步用于解决一个变量同一时刻被多个线程共享的问题(共享一个变量)。
threadLocal 使得一个变量在多个线程中各自拥有自己的副本(实现资源的隔离)。

原理:

ThreadLocal 中有一个map, 用于存储每一个线程的变量副本,其中map的key为 线程对象,value为对应线程的变量副本。

public class SimpleThreadLocal<T> 
    private Map valueMap = Collections.synchronizedMap(new HashMap());

    public void set(T value) 
        valueMap.put(Thread.currentThread(), value);
    

    public T get() 
        Thread currentThread = Thread.currentThread();
        T value = (T) valueMap.get(currentThread);
        if(value == null && !valueMap.containsKey(currentThread)) 
            value = initValue();
            valueMap.put(currentThread, value);
        
        return value;
    

    public void remove() 
        valueMap.remove(Thread.currentThread());
    

    public T initValue() 
        return null;
    

应用场景:

web应用分层结构中:同一变量在持久化,业务,展示层传递时(同一线程)。

接口方法:

    protected T initialValue(); //return the initial value for this thread-local
    public T get(); //return the current thread's value of this thread-local
    public void set(T value); //@param value the value to be stored in the current thread's copy of this thread-local.
    public void remove(); //Removes the current thread's value for this thread-local variable.

示例:

ThreadLocalContext.class
public class ThreadLocalContext 
    private static ThreadLocal<Integer> threadLocalNum = new ThreadLocal<Integer>() 
        @Override
        protected Integer initialValue() 
            return 0;
        
    ;

    public int getNextNum() 
        threadLocalNum.set(threadLocalNum.get()+1);
        return threadLocalNum.get();
    
ThreadLocalTest.class
public class ThreadLocalTest 
    public static void main(String[] args) 
        ThreadLocalContext threadLocalContext  = new ThreadLocalContext();
        WorkThread workThread1 = new WorkThread(threadLocalContext);
        WorkThread workThread2 = new WorkThread(threadLocalContext);
        WorkThread workThread3 = new WorkThread(threadLocalContext);
        workThread1.start();
        workThread2.start();
        workThread3.start();
    



class WorkThread extends Thread
    private ThreadLocalContext threadLocalContext;
    public WorkThread(ThreadLocalContext threadLocalContext) 
        this.threadLocalContext = threadLocalContext;
    

    public void run() 
        for(int i = 0; i < 5; i++) 
            System.out.println("thread[" + Thread.currentThread().getName()
                    + "] threadLocalNum [" + threadLocalContext.getNextNum() + "]");
        
    

以上是关于threadLocal 原理与使用的主要内容,如果未能解决你的问题,请参考以下文章

Java并发编程原理与实战二十五:ThreadLocal线程局部变量的使用和原理

[转]ThreadLocal使用

Java并发编程:ThreadLocal的使用以及实现原理解析

ThreadLocal的正确使用与原理

ThreadLocal的原理及用法

Java--ThreadLocal原理与使用