ThreadLocal 全面解析

版权声明:如需转载,请标明转载出处哦! https://blog.csdn.net/Z0157/article/details/81517802

ThreadLocal:
一.对ThreadLocal的理解
    1、线程的局部变量,是一种多线程间并发访问变量的解决方案。与其synchronized 等加锁方式不同。
    ThreadLocal完全不提供锁,是以空间换时间的手段,为每个线程提供变量的独立副本,那么每个线
    程可以访问自己内部的副本变量。以保证线程安全;
    2、性能没有优势,并发不高的情况下,加锁的性能会更好,但是作为一套完全与锁无关的线程
    解决方案,在高并发量或者竞争很激烈的场景,使用ThreadLocal可以一定程度减少锁竞争;
    3、结构:ThreadLocalMap 以ThreadLocal对象为key,任意对象为值的存储结构
    

二.ThreadLocal案例:
/**
 * Description:
 * User: zhurong
 * Date: 2018-08-08  21:40
 */
public class ThreadLocalDemo {
    public static ThreadLocal<String> th = new ThreadLocal<String>();
    public void setTh(String value){
        th.set(value);
    }
    public void getTh(){
        System.out.println(Thread.currentThread().getName() + ":" + this.th.get());
    }
    public static void main(String[] args) throws InterruptedException {
        final ThreadLocalDemo ct = new ThreadLocalDemo();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                ct.setTh("张三");
                ct.getTh();
            }
        }, "t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    ct.setTh("李四");
                    ct.getTh();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "t2");
        t2.start();
        t1.start();
    }
}
运行结果:
t1:张三
t2:李四

线程安全的结果;

由于在每个线程中都创建了副本,所以要考虑它对内存资源的消耗还是很大的;


三、API解析ThreadLocal
    ThreadLocal
        --    ThreadLocal() //构造方法,创建一个线程的本地变量
        --  withInitial() //延迟初始化一个value,对应的key是ThreadLocal对象
        --  get()  //获取ThreadLocal在当前线程中保存的变量副本
        --  set() //设置当前线程中变量的副本
        --  remove() //移除当前线程中变量的副本
        
三.ThreadLocal的应用场景
常见ThreadLocal使用场景为 用来解决 数据库连接、Session管理等
eg:(引用一工程中的源码)
private static final ThreadLocal threadSession = new ThreadLocal();
   public static Session getSession() throws InfrastructureException {
     Session s = (Session) threadSession.get();
     try {
         if (s == null) {
             s = getSessionFactory().openSession();
             threadSession.set(s);
         }
     } catch (HibernateException ex) {
         throw new InfrastructureException(ex);
     }
     return s;
 }


    

猜你喜欢

转载自blog.csdn.net/Z0157/article/details/81517802