突然发现之前总结的知识没有覆盖到ThreadLocal,这里续上一文是为补充。
首先说说什么是ThreadLocal。看名字感觉像是本地线程之意,其实不然。ThreadLocal其实是Thread的一个本地化对象,相当于线程访问其持有对象的代理,各个线程可通过它创建并访问各自的自有对象。说白了就是,线程可以创建自己的ThreadLocal保存想要保存的对象,实现跨越接口拿到保存的对象。
观其实现,其实是Thread内部维护了一个属性ThreadLocalMap,ThreadLocal本身相当于这个Map的key,用户输入的值就是value。每次通过ThreadLocal调用get()接口时,是先获取当前Thread对象,然后处理返回其ThreadLocalMap。set()接口亦然。
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) return (T)e.value; } return setInitialValue(); }
ThreadLocal的应用场景:
1.需要费线程安全的对象,又不想使用锁;
2.使用线程安全对象,又想避免开销;
3.方法间参数传递;
这里有一点注意:只有线程结束后,其ThreadLocal才会被回收,但是当我们使用线程池开发时线程是被复用的,所以ThreadLocal的生命周期无法预测。另外,如果ThreadLocal中包装了集合类或复杂对象,那么当开发者get出的时候可能不敢删除而是添加,最后可能导致内存泄漏。此问题值得关注。
java多线程解说【肆】_锁实现:wait()/notify()
java多线程解说【伍】_锁实现:ReentrantLock的实现
java多线程解说【柒】_锁实现:Lock/Condition的例子
java多线程解说【捌】_锁实现:读写锁ReentrantReadWriterLock
java多线程解说【玖】_锁实现:LockSupport工具类
java多线程解说【拾伍】_并发工具类:CountDownLatch
java多线程解说【拾陆】_并发工具类:CyclicBarrier
java多线程解说【拾柒】_并发工具类:Semaphore