ThreadLocal简介
个人理解
ThreadLocal 用的比较多的就是用来维护一个对象。让他在多线程访问下处于线程安全。来保证数据访问的正确性。多线程下不去共享同一个变量。一个线程只维护一个实例。线程若被销毁随着该线程所持有的对象也会被销毁。(销毁可以理解成回收)
看一手我写dome
@Slf4j
public class MyThreadLocal {
public static void main(String[] args) {
//多线程访问时,数据间隔离。一个线程只持有一个对象
ThreadLocal<Cat> threadLocal = new ThreadLocal<>();
for (int i = 1, size = 10; i <= size; i++) {
Cat cat = new Cat();
int finalI = i;
new Thread(() -> {
cat.setId(finalI);
cat.setAge(finalI);
cat.setName("我家的土猫:" + finalI);
cat.setSex("男");
threadLocal.set(cat);
log.info("main: " + threadLocal.get());
threadLocal.remove();
log.info("main: " + threadLocal.get());
}, "sxy"+i).start();
}
}
}
//10个线程,拥有10个对象
Cat cat = new Cat(); 这个对象一定要放在这个for循环里不然 控制台打印的数据不是我们想要的。
为什么?
一个线程持有一个实例副本。new对象的这个操作,如果放在for外的话,就是一个实例。
底层分析
//获取ThreadLocal中的对象
public T get() {
Thread t = Thread.currentThread();//返回对当前正在执行的线程对象的引用
ThreadLocalMap map = getMap(t); //当前:获取ThreadLocalMap
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);//这个map里是否有当前线程
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
//没有就是set
return setInitialValue();
}
//往: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);
}
//ThreadLocal 删除当前线程中的内存实例
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
ThreadLocalMap底层
//key当前线程 value 当前的引用对象
private ThreadLocalMap(ThreadLocalMap parentMap) {
Entry[] parentTable = parentMap.table;
int len = parentTable.length;
setThreshold(len);
table = new Entry[len];
for (int j = 0; j < len; j++) {
Entry e = parentTable[j];
if (e != null) {
@SuppressWarnings("unchecked")
ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
if (key != null) {
Object value = key.childValue(e.value);
Entry c = new Entry(key, value);
int h = key.threadLocalHashCode & (len - 1);
while (table[h] != null)
h = nextIndex(h, len);
table[h] = c;
size++;
}
}
}
}
2021年8月22号:
强软弱虚
强引用如果对象,有引用指向 就不会被回收
软引用 :内存不足时,进行回收。
弱引用:直接回收