1. 程式人生 > >利用ThreadLocal做執行緒快取減少資料庫的訪問

利用ThreadLocal做執行緒快取減少資料庫的訪問

場景:假設存在如下的表資料

student
name    age     sex     course
fang    20      男       1
guo     20      女       2

course
id      name
1       數學
2       語文
這時從資料庫中查詢出來student之後,考慮到資料量比較大的情況下,不適合做連表查詢,但是又需要知道學生選擇的課程名,則可以使用ThreadLocal來快取查詢出來的課程物件,以減少資料庫的訪問量,如下:
public class CacheMapContext<K, V> {

    private static final ThreadLocal<CacheMapContext> CACHE_CONTEXT_THREAD_LOCAL = new ThreadLocal<>();

    private Map<K, V> cache;

    public CacheMapContext() {
        this.cache = new HashMap<>(10);
        setContext(this);
    }

    private void setContext(CacheMapContext<K, V> context) {
        CACHE_CONTEXT_THREAD_LOCAL.set(context);
    }

    public static <K, V> CacheMapContext<K, V> getInstance(Class<K> k, Class<V> v) {
        return CACHE_CONTEXT_THREAD_LOCAL.get();
    }

    public void clean() {
        CACHE_CONTEXT_THREAD_LOCAL.remove();
    }

    /**
     * 獲取快取中的值
     *
     * @param k
     * @return
     */
    public V get(K k) {
        return this.cache.get(k);
    }

    public void put(K k, V v) {
        cache.put(k, v);
    }
}
使用:
@ResponseBody
    @RequestMapping(value = "test")
    public String test(TestConver testConver) {
        //初始化快取物件
        CacheMapContext<Long, String> cache = new CacheMapContext();
        //設定值
        cache.put(1L, "111111111");
        cache.put(2L, "222222222");
        System.out.println(testConver);
        get();
        //清除快取
        cache.clean();
        return testConver.toString();
    }

    public void get() {
        System.out.println("get--->" + CacheMapContext.getInstance(Long.class, String.class).get(1L));
    }
類似這樣, 當我們查詢出資料之後,快取到快取物件中,當方法結束後,清除快取物件,當課程id在之前查詢過了時,就可以在快取中命中了。