作者回复: 是的,对象的引用也被指向新的地址。
作者回复: 对的,调用wait之后,会进入到WaitSet队列,当调用notify之后,默认策略是将其从WaitSet队列转至EntryList队列中,再尝试获取锁。
作者回复: 如果线程没有销毁,也就是说该key值依然存在引用,即使是弱引用,也不会被回收掉。
作者回复: 是的,如果我们的线程在使用ThreadLocal的set之后就立刻销毁了,此时之前set的线程的key值通过垃圾回收回收掉,此时value则会存在内存泄漏,而马上又有下一个线程使用ThreadLocal的set,则会清除之前key为null的value,这种情况下是不会出现内存泄漏的。
也就是ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。
我们可以使用set之后,sleep下该线程,等待其他请求都一起使用完了set,这样很容易重现内存中的一部分对象无法回收掉。
作者回复: 好的,可以考虑。
作者回复: 我们可以读取大部分读写中间件实现源码,可以发现ThreadLocal使用的最为频繁,通常是通过ThreadLocal来获取当前线程的操作类型来实现读写数据源的切换。
在使用完之后实现remove操作,可以规避风险。
作者回复: 升级版本就好了,现在基本都是基于1.8版本了
作者回复: 不行,只是原来的引用置为null了,但堆中的字符串对象依然不会被回收掉
作者回复: 如果线程还存活,此时get是能获取到的,因为还存在强引用。如果线程生命周期已经结束,则ThreadLocal的线程本地变量将会失去引用,我们知道ThreadLocal是成员变量,如果key值没有设置为弱引用,则结束生命周期的线程变量依然会存在ThreadLocal中。
所以,当线程生命周期结束,ThreadLocal的key又为了弱引用,key值就会在垃圾回收期被回收掉。