java基础---多线程---threadlocal

ThreadLocal
能够为每个线程创建变量副本,就是说多个线程可以使用同一个threadlocal作为键,然后对应自己的副本值。可以有多个threadlocal变量,也就有多个相对应的值了。
===Thread源码分析,一个线程的局部变量存在哪里?
---通过Thread源码可以看到,线程内部使用静态内部类ThreadLocalMap来存局部变量.ThreadLocal.ThreadLocalMap threadLocals = null;
---ThreadLocalMap内部维护一个Entry类用来保存键值对,弱引用WeakReference包装ThreadLocal为key,局部变量为value,然后维护一个Entry的数组,因为一个线程的局部变量可以有非常多,都可以使用同一个map去保存,存在数组中.
---多个局部变量,就会有多个ThreadLocal,每个Threadlocal对应一个value值存入到map中
---局部变量可以看成键值对,int i=10在Entry数组中可以被替换修改
---ThreadLocalMap中的Entry在数量达到2/3的时候会进行垃圾回收,线程死亡的时候整个ThreadLocalMap也会进行垃圾回收.
 
 
---为什么键值对中ThreadLocal要用弱引用去包装呢?threadlocal为什么会内存泄漏呢?编程时候如果使用到Threadlocal最好做哪些处理呢?
因为涉及到threadlocalmap的垃圾回收问题。为了防止内存泄漏。常使用在hash表中
static class Entry extends WeakReference<ThreadLocal<?>>
强引用必须手动去删除,否则放在threadlocalMap中会内存泄漏。
----弱引用虚拟机会自动垃圾回收,在调用threadlocal的set,get,remove方法的时候Threadlocalmap会自动将key为null的值value赋值为null清除掉,来保证不会内存泄漏。
---使用到Threadlocal最好要进行一下threadlocal.remove()来清除掉map中key为空的entry
 
 
===api
get():获取当前线程的变量副本
set(T value):设置当前线程的变量副本
remove():移除当前变量的副本
initialValue():初始化变量,使得所有副本都用这个初始值。
 
===threadlocal和synchronized在同步问题上的区别
synchronized处理多线程并发问题,通过对一个对象加锁来实现同步,用时间换取空间。因为线程需要进行同步等待
threadlocal的优势是用空间换时间,通过对线程创建变量副本来处理并发访问的问题。线程访问自己的局部变量值,所以通过操作自身局部变量来达到同步的效果。
 
 

猜你喜欢

转载自www.cnblogs.com/buptyuhanwen/p/9546611.html