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号:
強軟弱虛
強引用如果對象,有引用指向 就不會被回收
軟引用 :記憶體不足時,進行回收。
弱引用:直接回收