ThreadLocal分析

ThreadLocal是一个为线程提供线程局部变量的工具类。 它的思想也十分简单,就是为线程提供一个线程私有的变量副本,这样多个线程都可以随意更改自己线程局部的变量,不会影响到其他线程。 不过需要注意的是,ThreadLocal提供的只是一个浅拷贝,如果变量是一个引用类型,那么就要考虑它内部的状态是否会被改变, 想要解决这个问题可以通过重写ThreadLocal的initialValue()函数来自己实现深拷贝,建议在使用ThreadLocal时一开始就重写该函数。

ThreadLocal与像synchronized这样的锁机制是不同的。 首先,它们的应用场景与实现思路就不一样,锁更强调的是如何同步多个线程去正确地共享一个变量, ThreadLocal则是为了解决同一个变量如何不被多个线程共享。从性能开销的角度上来讲,如果锁机制是用时间换空间的话, 那么ThreadLocal就是用空间换时间。

ThreadLocal中含有一个叫做ThreadLocalMap的内部类,该类为一个采用线性探测法实现的HashMap。 它的key为ThreadLocal对象而且还使用了WeakReference,ThreadLocalMap正是用来存储变量副本的。

ThreadLocal示例

/**
 * description:
 *
 * @author liyazhou
 * @since 2017-08-14 21:03
 */
public class ThreadLocalTest {
    private static ThreadLocal<Integer> x = new ThreadLocal<Integer>();

    public static void main(String... args){
        for (int i = 0; i < 2; i ++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int data = new Random().nextInt();
                    System.out.println(Thread.currentThread().getName() + " put data, " + data);
                    x.set(data);
                    new A().get();
                    new B().get();
                }
            }).start();
        }
    }

    static class A{
        void get(){
            int data = x.get();  // ThreadLocal的成员方法get()
            System.out.println("A from " + Thread.currentThread().getName() + " get data : " + data);
        }
    }

    static class B{
        void get(){
            int data = x.get();  // ThreadLocal的成员方法get()
            System.out.println("B from " + Thread.currentThread().getName() + " get data : " + data);
        }
    }
}

// 运行结果为
/*
    Thread-0 put data, -1698175580
    Thread-1 put data, 881572399
    A from Thread-0 get data : -1698175580
    A from Thread-1 get data : 881572399
    B from Thread-0 get data : -1698175580
    B from Thread-1 get data : 881572399
 */

results matching ""

    No results matching ""