首页 > 技术文章 > 线程ThreadLocal类

xuesheng 2017-12-06 10:51 原文

一、什么是ThreadLocal类

  ThreadLocal 在很多地方叫做本地变量,在有些地方叫做线程本地存储。ThreadLocal在每个线程中为每个变量都创建了一个副本,每个线程可以访问自己内部的副本变量,而不会对其它线程的副本变量造成影响。

 


 二、例子

public class MyThreadLocal {

    //private static  ThreadLocal<Integer> intLocal=new ThreadLocal<Integer>();
    private static ThreadLocal<Long> longLocal = new ThreadLocal<Long>();
    private static ThreadLocal<String> stringLocal = new ThreadLocal<String>();

    public void set() {
        //将线程的id设置到ThreadLocal
        longLocal.set(Thread.currentThread().getId());
        //将线程的Name设置到ThreadLocal
        stringLocal.set(Thread.currentThread().getName());
    }

    public String getString() {
        //从ThreadLocal中取出线程的变量副本
        return stringLocal.get();
    }

    public Long getLong() {
        //从ThreadLocal中取出变量副本
        return longLocal.get();
    }

    public static void main(String[] args) {
        MyThreadLocal threadLocal = new MyThreadLocal();
        threadLocal.set();
        String string = threadLocal.getString();
        System.out.println(Thread.currentThread().getName() + ": " + string);
        Long aLong = threadLocal.getLong();
        System.out.println(Thread.currentThread().getId() + ": " + aLong);


        Thread thread = new Thread() {
            public void run() {
                threadLocal.set();
                System.out.println(Thread.currentThread().getName() + ": " + threadLocal.getString());
                System.out.println(Thread.currentThread().getId() + ": " + threadLocal.getLong());
            }
        };
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

  如果看不懂没关系,下面会解释各个函数的意思。


 

三、ThreadLocal的方法

  

  Public T get(){}

  Public void set(T value){}

  Public void remove(){}

  Public T inittalValue(){}

 

  

  Get()方法是用来获取ThreadLocal在当前线程中保存的变量副本,set()是用来设置当前线程中变量的副本,remove()是用来移除房钱线程中的变量副本,initialValue()是一个Protected方法,一般是用来在使用时进行重写的。

 

  首先,在每个线程Thread内部都有一个ThreadLocal.ThreadLcoalMap 类型的成员变量threadLocals,该变量类似一个map,这个map妞儿会死用来存储实际的变量副本的,key存储每个ThreadLocal变量,value用来存储每个ThreadLocal存储的值即变量副本。

 

  初始时,ThreadLocals为空,当通过ThreadLocal变量调用get()方法或set()方法,就会对Thread类中threadLocals进行初始化,并且以当前的ThreadLocal变量为键值,以ThreadLocal要保存的变量的副本变量为value,存到threadLocals

 

总结:

 

  通过ThreadLocal创建的副本存储在每个线程自己的threadLocals

 

  threadLocals中用每个ThreadLocal作为key,用每个ThreadLocal要存储的变量副本为value

 

  在进行get()方法之前,需要先进行set(),否则会报空指针异常。

 

ThreadLocal类的使用场景:

 

常用来解决数据库连接、Session管理。

 


 

 

参考资料:

 

http://www.cnblogs.com/dolphin0520/

 

推荐阅读