ThreadLocal
使用场景
数据库事务:给个每个线程(请求)一个connection,这样我们关闭自动提交事务,就可以实现手动提交事务了<br>设置请求id等
原理
每个Thread对象都维护了一个ThreadLocalMap,里面存的就是当前线程个性化的数据,实现数据隔离的思想;那ThreadLocal相当于在一个<b>工具包</b>,可以对外提供每个Thread中的ThreadLocalMap中存储的东西,ThreadLocalMap也是Map,key值存的是ThreadLocal对象的引用,我们在使用ThreadLocal的时候,一般只new一个static的ThreadLocal,所以,多线程情况下,每个线程的ThreadLocalMap中key都一样,都是ThreadLocal的引用,value就属于个性化的东西了,原理大概就是这样。
理解
两大优点:相当于一个自己的<b>变量云存储</b><br>1、传递数据,保存每个线程保存的数据,需要的时候可以直接获取,避免了参数传递的麻烦<br>2、线程隔离:每个线程中中绑定的数据相互隔离,
弱引用和内存泄漏
概念:<br>内存溢出:内存的空间不够了<br>内存泄漏:堆内存的空间因为某种原因无法释放,最终导致内存溢出<br>弱引用:垃圾回收发现弱引用的对象,不管空间是否足够,都会回收空间
理解:<br>首先为什么会产生内训泄漏:加入我们已经使用完了ThreadLocal,但是线程依然在跑,这个时候,栈到堆的引用断开了,理论上,堆里面的ThreadLocal应该被GC,但是,ThreadLocalMap中,引用了ThreadLocal,因为key是ThreadLocal,所以导致没有用的TreadLocal无法被回收,造成ThreadLocal的内存泄漏。<br>那弱引用可以解决问题吗:答案是不能从根本上解决问题,弱引用代表ThreadLocal实例可以被回收,Entry中的key指向null了;但是,ThreadLocalMap作为Thread的成员变量,无法被回收,造成Entry中value的内存泄漏。jdk呢对这里做了优化,如果key指向为null,没有具体的ThreadLocal了,那么value也会置空,这样最大限度的避免了没有用的内存无法被回收的尴尬。<br>根本解决方法是:ThreadLocal用完之后,调用一下remove方法,这样,Entry里value就为空了;
hash冲突
线性探测法<br>Entry[] table可以看成一个<b>环形数组</b>
多线程同步有哪些呢
synchronized<br>lock<br>wait/notify<br>await/signalAll<br>countDownLatch<br>cyclibair<br>samephore