1. 程式人生 > 實用技巧 >ThreadLocal和強軟弱虛

ThreadLocal和強軟弱虛

強軟弱虛

強引用(StrongReference) : 最傳統的“引用”的定義,是指在程式程式碼之中普遍存在的引用賦值,即類似“Object obj=new Object()”這種引用關係。無論任何情況下,只要強引用關係還存在,垃圾收集器就永遠不會回收掉被引用的物件。

軟引用(SoftReference) :在系統將要發生記憶體溢位之前,將會把這些物件列入回收範圍之中進行第二次回收。如果這次回收後還沒有足夠的記憶體,才會丟擲記憶體溢位異常。

0bject obj = new Object(); //宣告強引用
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj 
= null; //銷燬強引用

弱引用(WeakReference) :被弱引用關聯的物件只能生存到下一次垃圾收集之前。當垃圾收集器工作時,無論記憶體空間是否足夠,都會回收掉被弱引用關聯的物件。

object obj = new Object(); //宣告強引用
WeakReference<object> wr = new WeakReference<object>(obj ) ;
obj = null; //銷燬強引用

虛引用(PhantomReference) :一個物件是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用來獲得一個物件的例項。為-一個物件設定虛引用關聯的唯一目的就是能在這個物件被收集器回收時收到一個系統通知。

ThreadLocal

set()方法

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

裡面的createMap()方法

void createMap(Thread t, T firstValue) {
        t.threadLocals 
= new ThreadLocalMap(this, firstValue); }

裡面的threadLocals繼承於Thread類,而ThreadLocalMap的key就是Entry,繼承自WeakReference

static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
}

內部結構

為什麼Entry要使用弱引用?

若是強引用,即使tl=null, 但key 的引用依然指向ThreadLocal物件,所以會有記憶體洩露,而使用弱引用則不會但還是有記憶體洩漏存在,ThreadLocal被回收,key的值 變成null,則導致整個value再也無法被訪問到,因此依然存在記憶體洩漏

應用

Spring裡面如何保證執行的都是同一個資料庫連線?

就是用的ThreadLocal,每個執行緒呼叫保證都是同一個連線