<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    吳密的博客

    每天進(jìn)步一點點
    posts - 12, comments - 1, trackbacks - 0, articles - 1

    threadLocal--簡單本地緩存

    Posted on 2010-09-10 13:44 xiaolang 閱讀(5643) 評論(0)  編輯  收藏

     

    首先,ThreadLocal 不是用來解決共享對象的多線程訪問問題的,一般情況下,通過ThreadLocal.set() 到線程中的對象是該線程自己使用的對象,其他線程是不需要訪問的,也訪問不到的。各個線程中訪問的是不同的對象。

    另外,說ThreadLocal使得各線程能夠保持各自獨(dú)立的一個對象,并不是通過ThreadLocal.set()來實現(xiàn)的,而是通過每個線程中的new 對象 的操作來創(chuàng)建的對象,每個線程創(chuàng)建一個,不是什么對象的拷貝或副本。

    個人版中有一個比較好的應(yīng)用場景,就是為會員查詢服務(wù)做的catche。

    在用戶的一次請求中需要多次查詢用戶的卡信息,會多次去調(diào)用遠(yuǎn)程服務(wù),造成性能上的浪費(fèi)。如果能在本地做一個簡單的cache,就可以省去遠(yuǎn)程調(diào)用的開銷,就可以如下圖所示

                                                                     
                           

    從圖中可以看出,優(yōu)化后的將一部分cache存在本地,就省去了遠(yuǎn)程調(diào)用的開銷,從一定程度上減輕了會員核心的壓力。

    Cache
    一般都有一個刷新時間的問題,時間長了,信息可能不準(zhǔn)確,時間短了,比較耗費(fèi)性能。最好的情況是這個cache過期了,不需要使用了,立即把清除,廢棄,這個最理想的情況。

    大家應(yīng)該知道,用戶從發(fā)起請求,到服務(wù)器響應(yīng)的這個過程中,在服務(wù)器中是在一個線程中的。如果我們吧查詢出來的東西放到這個線程中,到用戶請求結(jié)束時,把這些東西清理掉,應(yīng)該是一個不錯的cache方案。

    接下來的問題就簡單了,我們只需要把查詢的東西放到threadLocal就可以了。

    看大牛李磊如何實現(xiàn)這一點

    1.   
    首先需要初始化一個threadLocal

        /** 用于將會員信息保存在本地的線程變量*/

        private static ThreadLocal<List<UserInfo>>            localUserInfo      = new ThreadLocal<List<UserInfo>>() {
                                                                                     protected synchronized List<UserInfo> initialValue() {
                                                                                         return new ArrayList<UserInfo>();
                                                                                     } };

     
    2.   
    將查詢出來的東西放到threadLocal,下次查詢的時候,就可以先到threadLocal中取,如果沒有,再調(diào)用遠(yuǎn)程服務(wù)

            UserInfo userInfo = getFromLocalByCardNo(cardNo);
            if (userInfo == null) {
                userInfo = userInfoQueryService.findUserInfo(cardNo);
                putToLocal(userInfo);
            }
     
    3
    .用戶的請求結(jié)束,把這些內(nèi)容清理掉。
    為什么要把內(nèi)容清理掉
    如果一直存放在threadLocal,

    1是比較耗費(fèi)內(nèi)存;

    2是里面的內(nèi)容可能是過期的(用戶修改了信息,threadLocal里面沒有更新)

    3請求結(jié)束后需要清除ThreadLocal的一個很重要的原因就是,如果使用了線程池,在請求結(jié)束后,線程的生命周期還沒有結(jié)束,而是放回到池中,這樣下次再使用此線程的時候就會獲得上次的上下文了。

    我們?nèi)绾巫龅竭@一點呢?
    開始之前先給大家介紹一個接口,spring mvc中的。HandlerInterceptor

    這個接口中有三個方法
    preHandle
    在一個該方法會在Controller的方法執(zhí)行前會被調(diào)用,可以使用這個方法來中斷或者繼續(xù)執(zhí)行鏈的處理,當(dāng)返回true時,處理執(zhí)行鏈會繼續(xù),當(dāng)返回false時,則不會去執(zhí)行Controller的方法
    postHandle
    3個方法會在在controller的方法執(zhí)行之后,在DispatcherServlet類導(dǎo)向到view進(jìn)行render之前依次執(zhí)行。最有用的是使 用postHandleRender方法,因為它有ModelAndView 傳進(jìn)來,那么我們就可以在render view之前往view中添加額外的model對象,或者對view的去處進(jìn)行修改(例如下面的HTML還是用Excel來作為View ”例子就是對view進(jìn)行了更改)

    afterCompletion
    該方法會在render view完成后執(zhí)行,也可以說在請求過程(request processing)完成之后執(zhí)行。該方法可以用來清理資源(例如象blackboard building block release context)

    我們只需要在afterCompletion中把本次線程中的存放的信息清理掉,就可以了。
    大家應(yīng)該記得這一段代碼,初始化threadLocal并不需要這一點,

         static {
            ThreadLocalCleaner.register(localUserInfo);
            ThreadLocalCleaner.register(localCertifyStatus);
        }

    讓我們先看下ThreadLocalCleaner的代碼

        /**
         *
    清理所有的線程變量。
         */
        public static void clear() {
            for (ThreadLocal<?> tl : tls) {
                tl.remove();
            }
        }

        /**
         * @param tl
         */
        public static void register(ThreadLocal<?> tl) {
            tls.add(tl);
        }
     
    方 法register將初始化的ThreadLocal放到一個總的ThreadLocal里,方法clear將總的ThreadLocal里面的內(nèi)容清 空。我們只需要在HandlerInterceptor實現(xiàn)類中的afterCompletion方法中把clear調(diào)用一下就可以了。

     


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲AV无码一区二区乱子仑| 中国内地毛片免费高清| 免费一看一级毛片| 国产成人AV免费观看| 亚洲理论片在线中文字幕| 国产真人无遮挡作爱免费视频| a视频在线免费观看| 亚洲综合久久一本伊伊区| 亚洲黄片毛片在线观看| 免费无码毛片一区二区APP| 亚洲av无码一区二区三区在线播放 | 91精品免费国产高清在线| 精品国产_亚洲人成在线| 亚洲va在线va天堂va四虎| 女人张开腿等男人桶免费视频| 中文字幕成人免费高清在线| 亚洲日韩一中文字暮| 亚洲高清专区日韩精品| 国产资源免费观看| 亚洲日本在线免费观看| aa午夜免费剧场| 国产亚洲sss在线播放| 亚洲国产精彩中文乱码AV| 精品少妇人妻AV免费久久洗澡| 三年片在线观看免费观看大全一 | aa毛片免费全部播放完整| 一本色道久久88亚洲精品综合| 久久亚洲国产成人亚| 又粗又硬又黄又爽的免费视频| 91成人免费观看网站| 中文字幕日本人妻久久久免费| 免费人成视频在线播放| 亚洲欧美第一成人网站7777| 亚洲女人初试黑人巨高清| 久久精品亚洲综合专区| 亚洲国产精品无码久久久久久曰 | 亚洲乱码卡一卡二卡三| 亚洲国产精久久久久久久| 久久久久亚洲精品天堂久久久久久 | 国产无遮挡又黄又爽免费视频| 免费影院未满十八勿进网站|