java并发编程:线程变量-ThreadLocal类
用处:ThreadLoca持有的数据为每条线程生成一个独立的变量副本
思想:如果一个资源会引起线程竞争,那就为每一个线程配置一个资源。相比于synchronized是一种空间换时间的策略
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其他线程所对应的副本。常用于用户登录控制,如记录session信息
ThreadLocal其实就是一个特殊的容器,也有get、set方法
每一个ThreadLocal只能维护一个共享资源,一旦声明ThreadLocal实例,线程在调用get()方法获取资源副本的时候,就可以自动设置绑定到该线程本身
ThreadLocal泛型指定持有的变量类型,创建的时候可以使用匿名对象new ThreadLocal(){ initialValue()}初始化值,或者做一些别的操作
ThreadLocal类中可重载的方法
- set(value):设置值
- get():取值
- remove():移除值
- initialValue():如果get的时候还没有设置值,就使用这个方法进行初始化
- 一般会使用initialValue()方法提供一个初始值
使用ThreadLocal是否会造成内存泄漏
- 每一个线程对资源副本都有一个隐式引用:只要线程还在运行,只要ThreadLocal还是可以获取的。当一个线程运行结束销毁时,所有的资源副本都是可以被来及回收的。所以理论上不会造成内存泄漏
- ThreadLocal对Thread的引用全部通过局部变量完成,而没有一个全局变量,而实际的资源副本则存储在Thread的自身的属性ThreadLocalMap中,这说明,其实ThreadLocal只是关联一个Thrad和其资源副本的桥梁,并且实际上Thread和资源副本的声明周期是紧密相连的,确实如ThreadLocal所说,在线程被回收的时候,其资源副本也会被回收,虽然ThreadLocal是静态的,但是它既不引用Thread,也不引用ThreadLocalMap。
- 如果多个线程并发访问的的对象实例只允许,也只能创建一个,那就没有别的办法了,老老实实使用同步机制来访问吧
心里有束光,眼里有片海