ThreadLocal的理解与使用
来源:互联网 发布:法剧 知乎 编辑:程序博客网 时间:2024/05/21 08:52
首先来看一下多线程问题:
class Test{ private static Integer data = 0;//使用Integer普通变量保存数据 public static void set(Integer num){ data = num; } public static Integer get(){ System.out.println("num ==> " +data); return data; }}public class CopyOfMainTest{ public static void main(String[] args){ for(int i=0;i<10;i++){ final int num = i; new Thread(){ public void run(){ Test.set(num); Test.get(); } }.start(); } }}
执行的结果如下:
num ==> 4
num ==> 0
num ==> 4
num ==> 4
num ==> 3
num ==> 5
num ==> 7
num ==> 9
num ==> 9
num ==> 8
分析:可以看到以下多个线程中data的值时一样的,使得数据结果很混乱,按照正常的思维模式,每一个线程应该得到一个数据,从0到9,这就是我们经常说的线程安全问题,这里肯定是不安全的。当然了你可以用synchronized去解决这个问题,但是多线程的并发处理的效率就会大大折扣。
来看一个用ThreadLocal存放变量的例子:
//使用ThreadLocal保存数据class Test{ public static ThreadLocal<Integer> local = new ThreadLocal<Integer>(); public static void set(Integer num){ local.set(num); } public static Integer get(){ System.out.println("num ==> " + local.get()); return local.get(); }}public class CopyOfMainTest{ public static void main(String[] args){ for(int i=0;i<10;i++){ final int num = i; new Thread(){ public void run(){ Test.set(num); Test.get(); } }.start(); } }}
执行的结果如下:
num ==> 0
num ==> 1
num ==> 2
num ==> 3
num ==> 6
num ==> 5
num ==> 8
num ==> 4
num ==> 9
num ==> 7
只是顺序上变了而已,每个线程都得到自己应该得到的Integer变量值。
分析原因:
通过对java API的查阅,发现Tread 和ThreadLocal都在java.lang包下。在java.lang.Thread源码中,有这样一段代码。这个threadLocals就是那些设计者们已经为我们考虑了在线程中存放变量的问题。
/* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null;在看ThreadLocal源码:
/** * Returns the value in the current thread's copy of this * thread-local variable. If the variable has no value for the * current thread, it is first initialized to the value returned * by an invocation of the {@link #initialValue} method. * * @return the current thread's value of this thread-local */ public T get() {//get方法 Thread t = Thread.currentThread();//获取当前上下文线程(哪个线程在调用该方法) ThreadLocalMap map = getMap(t);//把当前线程作为参数丢给getMap方法,返回一个ThreadLocal的内置对象ThreadLocalMap (map) if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this);//取出当前上下ThreadLocal对象对应的值 Entry getEntry(ThreadLocal key) if (e != null) return (T)e.value; } return setInitialValue(); }/** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. */ public void set(T value) {//set方法 Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value);//把当前的ThreadLocal对象作为key把值存入,set(ThreadLocal key, Object value) else createMap(t, value); }/** * Get the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
通过对源码的分析发现,ThreadLocal在存变量的时候是根据当前上下文线程 和 当前ThreadLocal对象存入数值的。所以当调用get方法时,根据当前上下文线程和ThreadLocal对象就取出了自己唯一的那个值,而不会取到别的线程的值。
强烈推荐两篇文章:
http://qiankunli.github.io/2014/09/02/ThreadLocal.html
http://woshixy.blog.51cto.com/5637578/1275284
注册没几天,就写了一篇,写的不好,请大家提出意见,慢慢改进。
1 0
- ThreadLocal的理解与使用
- ThreadLocal理解与使用
- ThreadLocal类的理解与使用
- ThreadLocal的使用理解
- threadlocal的理解与体会
- java中的ThreadLocal类的理解与使用
- ThreadLocal的理解和使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- ThreadLocal的设计与使用
- 本征向量、PCA和熵的基础教程
- Centos6.8 x64位一键安装google-chrome-stable浏览器
- Android注解收集
- less 从末尾查看日志
- Thinkphp3.2.3设置session周期无效的问题
- ThreadLocal的理解与使用
- 使用 CollapsingToolbarLayout ,可折叠的顶部导航栏
- shell
- poj 1789 Truck History
- Java学习(二)
- poj 1321 状态压缩dp-棋盘问题
- 位移遍历输出整数2进制
- memcached hash一致性算法
- 【POJ】2001 - Shortest Prefixes(字典树)