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

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

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

    吳密的博客

    每天進步一點點
    posts - 12, comments - 1, trackbacks - 0, articles - 1

    threadLocal--簡單本地緩存

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

     

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

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

    個人版中有一個比較好的應用場景,就是為會員查詢服務做的catche

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

                                                                     
                           

    從圖中可以看出,優化后的將一部分cache存在本地,就省去了遠程調用的開銷,從一定程度上減輕了會員核心的壓力。

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

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

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

    看大牛李磊如何實現這一點

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

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

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

     
    2.   
    將查詢出來的東西放到threadLocal,下次查詢的時候,就可以先到threadLocal中取,如果沒有,再調用遠程服務

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

    1是比較耗費內存;

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

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

    我們如何做到這一點呢?
    開始之前先給大家介紹一個接口,spring mvc中的。HandlerInterceptor

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

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

    我們只需要在afterCompletion中把本次線程中的存放的信息清理掉,就可以了。
    大家應該記得這一段代碼,初始化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里面的內容清 空。我們只需要在HandlerInterceptor實現類中的afterCompletion方法中把clear調用一下就可以了。

     


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


    網站導航:
     
    主站蜘蛛池模板: 亚洲A∨精品一区二区三区下载 | 亚洲春黄在线观看| 伊人免费在线观看| 亚洲一区AV无码少妇电影☆| 国产97视频人人做人人爱免费| 免费在线一级毛片| 特黄aa级毛片免费视频播放| 日本亚洲成高清一区二区三区| 免费在线人人电影网| 精品亚洲一区二区三区在线观看| 一区二区3区免费视频| 亚洲成人免费网址| 亚洲国产成人精品久久| 免费无码又爽又黄又刺激网站| 免费人成网站7777视频| 日本激情猛烈在线看免费观看| ZZIJZZIJ亚洲日本少妇JIZJIZ| 国产激情久久久久影院老熟女免费| 亚洲人成人77777网站| 69视频在线是免费观看| 亚洲综合色婷婷在线观看| a级毛片毛片免费观看永久| 亚洲av日韩av天堂影片精品| 国产91免费视频| 欧美色欧美亚洲另类二区| 亚洲免费日韩无码系列 | 免费人成网站7777视频| eeuss影院免费92242部| 色婷婷亚洲十月十月色天| 黄页网站免费观看| 日本视频免费观看| 久久精品国产亚洲av水果派| 成人免费无码大片A毛片抽搐色欲| 少妇亚洲免费精品| 亚洲AV日韩AV永久无码下载| 日韩高清免费在线观看| 巨胸喷奶水www永久免费| 亚洲videosbestsex日本| 亚洲成av人片天堂网老年人| 日本免费大黄在线观看| 日本亚洲欧美色视频在线播放|