线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。
今天动手体验了一下ThreadLocal的基本功能
带注释的是ThreadLocal变量,不带注释的是普通string,下面通过模拟三个线程来对比运行结果。
String类型结果:
-1184077754
init:0
-1184077754
init:0
-1184077754
init:0
ThreadLocal类型结果:
-1184077754
init:0
-1184077753
init:1
-1184077752
init:2
由于count静态变量是线程共享的,在string类型tl赋值时候赋值语句只运行了一遍,count变量始终为0,并且字符串tl的hashcode始终相同。
而ThreadLocal中get方法返回的string字符串赋值运行了三遍,三个hashcode均不相同,而且count变量也先后为0 1 2三个不同的值。
说明threadlocal为每个线程创建了一个本地变量,只有该线程可以访问,简单来说,就是把util中的tl复制一份作为局部变量来使用,避免了多线程对该变量造成的同步问题。
网上找来的模拟代码来分析一下原理
可以看到实质上ThreadLocal就是一个同步的Map对象,key是当前线程,value是当前线程该变量的值,从而实现了变量线程本地化。
一句话总结,每个线程都会复制一份ThreadLocal申明的变量给自己使用,该变量在每个线程中均是独立的,其他线程不可访问的。