在之前的文章中,已经发布了常见的面试题,这里我花了点时间整理了一下对应的解答,由于个人能力有限,不一定完全到位,如果有解答的不合理的地方还请指点,在此谢过。
本文主要描述的是java多线程中提供的一些常用框架threadlocal、线程池。线程池是面试的一大热点问题,非常有必要掌握线程池的原理和相关源码;Threadlocal在某些特定的场合下作用非常大,掌握其核心内容和使用方法也非常有必要。如果对java多线程感兴趣的同学可以看下公众号里多线程系列的文章,也许会对你有些帮助。
ThreadLocal有了解么?ThreadlocalMap的key 和value是什么?怎么保证内存不会泄露?
Threadlocal是线程本地变量类,该类的作用是可以在一个线程的保存变量,该变量只有该线程可以访问,这样可以在一定程度上避免使用锁。另一个作用是避免同一个线程上下文传递。Threadlocal的值是通过Thread类中的ThreadLocalMap进行存储。ThreadLocalMap的每个entry对象是一个弱引用对象,key是threadLocal对象,value是要存入的值。我们看下ThreadLocalMap的定义:
static class ThreadLocalMap {
//静态内部类,每个entry对象key都是一个弱引用对象
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
//key 是ThreadLocal 对象,value是具体的值
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private static final int INITIAL_CAPACITY = 16;//初始值 16
private Entry[] table;//entry对象
private int size = 0;//entry的大小
private int threshold;//扩容的阈值
}
需要了解的是,ThreadLocalMap在解决hash冲突的时候,使用的是线性探测的方式来解决的。
private void set(ThreadLocal<?> key, Object value) {
Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (len-1);
for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) {//一直寻找下一个空位
//...
}
}
Threadlocal为什么会发生内存泄漏?在这里,先提一下java的四种引用及其回收机制:强、软、弱、虚。强引用是不会被垃圾回收器回收的,软引用是没有内存的时候会被回收,弱引用和虚引用在发生垃圾回收的时候被回收。所以如果我们不希望软、弱被回收的话,我们只要使用一个强