Java ThreadLocal类理解与浅析

Java ThreadLocal类理解与浅析

    • Java ThreadLocal类理解与浅析
      • 观点
      • 官方文档
        • 官方描述
        • 个人翻译
      • ThreadLocal使用实现原理
      • 对于线程副本的理解
      • 设计意义
      • 应用场景
      • 参考文章

观点

ThreadLocal类不是为了解决一些网上文章所说的线程同步问题的
ThreadLocal也不是用来解决对象共同访问问题的
如何得到这些观点,以及ThreadLocal真的适用场景什么请看我下面的分析。

官方文档

官方描述:

* Implements a thread-local storage, that is, a variable for which each thread
* has its own value. All threads share the same {@code ThreadLocal} object,
* but each sees a different value when accessing it, and changes made by one
* thread do not affect the other threads. The implementation supports
* {@code null} values.

个人翻译:

实现一个线程局部存储,即,每个线程都含有自己值的变量。所有的线程共享一个ThreadLocal对象,但是每个线程访问的时候都会有不同的值,并且对一个线程的值进行更新不会影响到其他线程的值。该实现支持null。

ThreadLocal使用实现原理

首先说明一下ThreadLocal的处理步骤,
(1)创建一个ThreaLocal,在不同线程中set(Object o),为不同的线程设置线程局部变量
(2)ThreadLocal将会以该ThreadLocal的实例作为键,去Thread中存放数据的Map(ThreadLocalMap

protected T initialValue() {
    //默认实现是返回null,子类可以重写
    return null;
}

所以,理解了实现原理,就应该理解ThreadLocal类不是为了解决一些网上文章所说的线程同步问题的,因为ThreadLocal本质上只是对于同一个值在不同的现在创建各自的对象而已。

对于线程副本的理解

你需要每个线程里set不同的实例,才会实现不同线程的拥有相互独立的局部变量,若你每个线程set的时候是同一个实例,get的时候也是得到同一实例,参照我的实验代码:

publicclassThreadLocalTest implementsRunnable{

     publicstaticfinal ThreadLocalthreadLoacl1= newThreadLocal();
     privatestaticfinal inttimes= 40;
     privatestaticString str= new String("myy");
     privatestaticAtomicInteger integer= new AtomicInteger(0);

     @Override
     publicvoidrun() {
          threadLoacl1.set(integer);
          AtomicInteger atomic =threadLoacl1.get();
          for(inti =0;iout.println(this.toString()+": i="+atomic.addAndGet(1));
          }
     }

     publicstaticvoid main(String args[])
     {
          for(inti=0;i<3;i++)
          {
              newThread(newThreadLocalTest()).start();
          }
     }
}

输出结果为:

com.myy.threadloacl.ThreadLocalTest@684be8b8: i=1
com.myy.threadloacl.ThreadLocalTest@79b7d13e: i=3
com.myy.threadloacl.ThreadLocalTest@79b7d13e: i=4
com.myy.threadloacl.ThreadLocalTest@4f9bbd86: i=2
......
com.myy.threadloacl.ThreadLocalTest@684be8b8: i=119
com.myy.threadloacl.ThreadLocalTest@684be8b8: i=120

若按照正常的说法应该是每个线程一个数据副本,最终结果应该是3个40,而结果我们看到了,是120,其实是访问一个对象,而不是三个副本。

所以网上有些文章说ThreadLocal也不是用来解决对象共同访问问题的,因为对于不同线程中的同一局部变量,是指向不同实例还是同一实例,其实是由我们自己决定的。

设计意义

ThreadLocal不是用来解决对象共享访问问题的,而是提供了线程保持对象的方法和避免麻烦的参数传递访问方式。

应用场景

ThreadLocal的应用场合,最适合的是按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。

参考文章

http://www.iteye.com/topic/103804

你可能感兴趣的:(我的总结)