两年前看到一个朋友在朋友圈发错误的坚持和轻易的放弃哪个是对的,这句话其实是很矛盾的一句话,自己选择的路到底是不是对的,这是一个大大的问号,尤其在遇到困难时,这个疑问更加被放大,其实,在到达终点前,我们大部分人可能都走在黑夜中,而能做的就是努力争取到一个照明的灯,而这台照明的灯也是要不断的争取来的。
下面说说TheadLocal,他是什么呢?
理论上,其实java中的每一个变量都可以被外部的线程访问到,那如果我想让这个线程之属于我自己的线程,要怎么做呢,threadLocal就是来做这件事的,也就是线程私有。
线程私有能怎样,他能实现线程安全,这就是他诞生的目的
那他是怎么实现的呢
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
这个时候他的set方法,我们看到最终是放到了
ThreadLocalMap
这个Map中,也就是说,其实他是通过建立副本的显示,来实现线程私有。
他的key是弱引用的,而value是强引用的,弱引用在没有外部引用的情况下,垃圾回收就会将他清理。
那他和sync都能实现线程安全,他们有什么不同呢?
区别是 一个是以时换空 一个是以空换时 sync类以时换空 通过阻塞来减少内存的消耗 ThreadLocal 是通过新建一个线程 来减少时间的消耗 这里说说java的几种引用,java的引用分为强引用,软引用,弱引用,虚引用。
强引用就是Object object = new Object() 这个是我们经常用到的,对于强引用而言,就算object = null他还是不回被垃圾回收,只有引用不可达才会被回收,那怎样才是引用不可达,我思考了很久,其实就是放在堆中的对象找不到引用了。而引用在哪里呢,引用是存在栈上的,而栈中的引用会随着方法执行完就会处理掉,这个引用也就结束了。
软引用就是在程序即将oom的时候,就会执行gc,如果是软引用,那么不管你有没有被引用,都会把他回收
弱引用,这个弱引用就是,如果弱引用的对象,没有了引用,那么在下一次YGC的时候就会被垃圾回收,ThreadLocalMapkey使用的就是弱引用,同时他的key就是ThreadLocal本身,所以说如果ThreadLocal结束了,那么他马上就会GC
虚引用就不说了,很少用。
ThreadLocal也存在一些副作用,比如内存泄露问题,ThreadLocalMap中的key使用的是弱引用,但是value并不是,把key情调之后,value还在占用内存,这时候就会内存泄露了,索引执行完要执行下remove方法,此外还有脏数据问题