成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

Java構(gòu)建高效結(jié)果緩存方法示例

瀏覽:175日期:2022-09-02 13:16:37

緩存是現(xiàn)代應(yīng)用服務(wù)器中非常常用的組件。除了第三方緩存以外,我們通常也需要在java中構(gòu)建內(nèi)部使用的緩存。那么怎么才能構(gòu)建一個高效的緩存呢? 本文將會一步步的進行揭秘。

使用HashMap

緩存通常的用法就是構(gòu)建一個內(nèi)存中使用的Map,在做一個長時間的操作比如計算之前,先在Map中查詢一下計算的結(jié)果是否存在,如果不存在的話再執(zhí)行計算操作。

我們定義了一個代表計算的接口:

public interface Calculator<A, V> { V calculate(A arg) throws InterruptedException;}

該接口定義了一個calculate方法,接收一個參數(shù),并且返回計算的結(jié)果。

我們要定義的緩存就是這個Calculator具體實現(xiàn)的一個封裝。

我們看下用HashMap怎么實現(xiàn):

public class MemoizedCalculator1<A, V> implements Calculator<A, V> { private final Map<A, V> cache= new HashMap<A, V>(); private final Calculator<A, V> calculator; public MemoizedCalculator1(Calculator<A, V> calculator){ this.calculator=calculator; } @Override public synchronized V calculate(A arg) throws InterruptedException { V result= cache.get(arg); if( result ==null ){ result= calculator.calculate(arg); cache.put(arg, result); } return result; }}

MemoizedCalculator1封裝了Calculator,在調(diào)用calculate方法中,實際上調(diào)用了封裝的Calculator的calculate方法。

因為HashMap不是線程安全的,所以這里我們使用了synchronized關(guān)鍵字,從而保證一次只有一個線程能夠訪問calculate方法。

雖然這樣的設(shè)計能夠保證程序的正確執(zhí)行,但是每次只允許一個線程執(zhí)行calculate操作,其他調(diào)用calculate方法的線程將會被阻塞,在多線程的執(zhí)行環(huán)境中這會嚴重影響速度。從而導致使用緩存可能比不使用緩存需要的時間更長。

使用ConcurrentHashMap

因為HashMap不是線程安全的,那么我們可以嘗試使用線程安全的ConcurrentHashMap來替代HashMap。如下所示:

public class MemoizedCalculator2<A, V> implements Calculator<A, V> { private final Map<A, V> cache= new ConcurrentHashMap<>(); private final Calculator<A, V> calculator; public MemoizedCalculator2(Calculator<A, V> calculator){ this.calculator=calculator; } @Override public V calculate(A arg) throws InterruptedException { V result= cache.get(arg); if( result ==null ){ result= calculator.calculate(arg); cache.put(arg, result); } return result; }}

上面的例子中雖然解決了之前的線程等待的問題,但是當有兩個線程同時在進行同一個計算的時候,仍然不能保證緩存重用,這時候兩個線程都會分別調(diào)用計算方法,從而導致重復計算。

我們希望的是如果一個線程正在做計算,其他的線程只需要等待這個線程的執(zhí)行結(jié)果即可。很自然的,我們想到了之前講到的FutureTask。FutureTask表示一個計算過程,我們可以通過調(diào)用FutureTask的get方法來獲取執(zhí)行的結(jié)果,如果該執(zhí)行正在進行中,則會等待。

下面我們使用FutureTask來進行改寫。

FutureTask

@Slf4jpublic class MemoizedCalculator3<A, V> implements Calculator<A, V> { private final Map<A, Future<V>> cache= new ConcurrentHashMap<>(); private final Calculator<A, V> calculator; public MemoizedCalculator3(Calculator<A, V> calculator){ this.calculator=calculator; } @Override public V calculate(A arg) throws InterruptedException { Future<V> future= cache.get(arg); V result=null; if( future ==null ){ Callable<V> callable= new Callable<V>() {@Overridepublic V call() throws Exception { return calculator.calculate(arg);} }; FutureTask<V> futureTask= new FutureTask<>(callable); future= futureTask; cache.put(arg, futureTask); futureTask.run(); } try { result= future.get(); } catch (ExecutionException e) { log.error(e.getMessage(),e); } return result; }}

上面的例子,我們用FutureTask來封裝計算,并且將FutureTask作為Map的value。

上面的例子已經(jīng)體現(xiàn)了很好的并發(fā)性能。但是因為if語句是非原子性的,所以對這一種先檢查后執(zhí)行的操作,仍然可能存在同一時間調(diào)用的情況。

這個時候,我們可以借助于ConcurrentHashMap的原子性操作putIfAbsent來重寫上面的類:

@Slf4jpublic class MemoizedCalculator4<A, V> implements Calculator<A, V> { private final Map<A, Future<V>> cache= new ConcurrentHashMap<>(); private final Calculator<A, V> calculator; public MemoizedCalculator4(Calculator<A, V> calculator){ this.calculator=calculator; } @Override public V calculate(A arg) throws InterruptedException { while (true) { Future<V> future = cache.get(arg); V result = null; if (future == null) {Callable<V> callable = new Callable<V>() { @Override public V call() throws Exception { return calculator.calculate(arg); }};FutureTask<V> futureTask = new FutureTask<>(callable);future = cache.putIfAbsent(arg, futureTask);if (future == null) { future = futureTask; futureTask.run();}try { result = future.get();} catch (CancellationException e) { log.error(e.getMessage(), e); cache.remove(arg, future);} catch (ExecutionException e) { log.error(e.getMessage(), e);}return result; } } }}

上面使用了一個while循環(huán),來判斷從cache中獲取的值是否存在,如果不存在則調(diào)用計算方法。

上面我們還要考慮一個緩存污染的問題,因為我們修改了緩存的結(jié)果,如果在計算的時候,計算被取消或者失敗,我們需要從緩存中將FutureTask移除。

本文的例子可以參考https://github.com/ddean2009/learn-java-concurrency/tree/master/MemoizedCalculate

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標簽: Java
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
国产精品videosex极品| 亚洲女人的天堂| 亚洲免费观看高清| 欧美日韩岛国| 国产日韩精品一区二区三区| 99re热这里只有精品免费视频| 欧美一区二区视频在线观看2022| 黄网站免费久久| 欧美日韩精品一区二区| 久久精品国产亚洲aⅴ| 欧美日韩你懂的| 国产电影精品久久禁18| 在线成人午夜影院| 久久精品国产色蜜蜜麻豆| 色94色欧美sute亚洲13| 日韩在线播放一区二区| 色视频成人在线观看免| 免费观看30秒视频久久| 欧美性猛片xxxx免费看久爱| 激情综合色综合久久| 777奇米成人网| 国产成人8x视频一区二区| 欧美一区二区三区成人| 成人一区二区三区视频| 日韩免费高清视频| 欧美一区二区三区在线免费观看| 国产精品久久久久永久免费观看| 亚洲高清123| 一区二区三区精品久久久| 久久精品中文| 蜜臀av性久久久久蜜臀aⅴ流畅 | 色婷婷久久99综合精品jk白丝| 日韩高清一级片| 欧美日韩国产一级片| 国产激情91久久精品导航| 精品国产电影一区二区| 国产综合激情| 亚洲一区二区三区四区在线免费观看| 久久精品国产清高在天天线| 老司机精品视频线观看86| 日韩午夜激情av| 欧美视频亚洲视频| 亚洲精品你懂的| 欧美亚洲综合另类| 粉嫩嫩av羞羞动漫久久久| 国产亚洲一区二区三区四区| 亚洲国产精品第一区二区| 日韩精品成人一区二区三区| 欧美久久久一区| 欧美aa国产视频| 亚洲精品免费一二三区| 色av一区二区| www.亚洲免费av| 亚洲男女一区二区三区| 欧美亚洲一区二区三区| 激情欧美日韩一区二区| 久久网站热最新地址| 99精品视频网| 国产一区二区中文字幕| 国产精品久久久久久久第一福利 | www.av亚洲| 亚洲人成网站色在线观看| 在线免费精品视频| 91污片在线观看| 亚洲国产成人精品视频| 91麻豆精品国产| 欧美亚韩一区| 日本人妖一区二区| 久久综合久久99| 亚洲欧美日韩精品久久久| 国产老妇另类xxxxx| 欧美激情中文字幕| 久久精品人人做人人爽电影蜜月| 国产精品一区二区视频| 国产精品久久久久久久久快鸭| 欧洲生活片亚洲生活在线观看| 欧美一区二区三区久久精品| 日韩高清不卡一区| 国产午夜精品美女毛片视频| 乱人伦精品视频在线观看| 成人av网站大全| 一区二区三区国产精华| 91麻豆精品国产91久久久久久久久 | 免费高清在线一区| 久久嫩草精品久久久精品一| 欧美中文字幕| 成年人午夜久久久| 亚洲不卡一区二区三区| 久久亚洲捆绑美女| 久久裸体视频| 91麻豆精东视频| 香蕉久久夜色精品国产使用方法| 日韩丝袜情趣美女图片| 国产精品乱码| 91蜜桃传媒精品久久久一区二区| 免费看日韩a级影片| 中文幕一区二区三区久久蜜桃| 欧美色图天堂网| 一区在线电影| 懂色一区二区三区免费观看| 一区二区三区视频在线观看| 精品国产电影一区二区| 在线精品视频免费播放| 国内精品福利| 国产精品一区久久久久| 一区二区三区精品视频| 日韩精品一区二区三区蜜臀| 亚洲一区三区视频在线观看| 91亚洲午夜精品久久久久久| 蜜臂av日日欢夜夜爽一区| 亚洲视频网在线直播| 日韩一区二区三区电影| 欧美一级网站| 欧美 亚欧 日韩视频在线| 激情综合五月婷婷| 亚洲一二三区不卡| 国产欧美一区视频| 欧美猛男超大videosgay| 中文一区在线| 99re热视频这里只精品| 蓝色福利精品导航| 国产精品初高中害羞小美女文| 欧美va日韩va| 欧美日韩久久久一区| 国产日韩一区二区三区在线播放| 91小视频免费观看| 国产成人精品一区二区三区四区 | 亚洲香蕉视频| a美女胸又www黄视频久久| 日韩av一级片| 一区二区三区中文字幕精品精品| 精品盗摄一区二区三区| 欧美日韩精品专区| 美玉足脚交一区二区三区图片| 亚洲高清视频一区| 欧美日韩在线不卡一区| 成人av影院在线| 国产成人午夜精品影院观看视频| 秋霞电影一区二区| 午夜精品久久久久影视| 一区二区三区四区国产精品| 国产精品毛片久久久久久久| 久久久久久亚洲综合| 欧美大片免费久久精品三p| 色乱码一区二区三区88| 午夜在线观看免费一区| 91久久极品少妇xxxxⅹ软件| 欧美国产免费| 色综合色狠狠综合色| 国产精品自在在线| 毛片av一区二区三区| 亚洲成人av一区二区三区| 国产精品美女久久久久久久久| 精品国产露脸精彩对白| 日韩一级高清毛片| 在线播放国产精品二区一二区四区| 久久久久免费| 国产精品一区二区欧美| 伊人久久综合| 97精品视频在线观看自产线路二| 国产乱子伦一区二区三区国色天香 | 亚洲日本免费电影| 国产日韩综合av| 欧美大白屁股肥臀xxxxxx| 欧美日韩一区二区三区免费看| 快she精品国产999| 久久精品女人的天堂av| 国产一区二区精品| 黄色国产精品一区二区三区| 欧美精品成人| 91视频在线观看| 91影院在线免费观看| 不卡一区二区在线| 成人性生交大片免费看中文| 国产精品一二三四五| 国产精品白丝jk黑袜喷水| 久久国产精品99精品国产| 毛片不卡一区二区| 奇米亚洲午夜久久精品| 日本免费新一区视频| 日本伊人午夜精品| 麻豆久久一区二区| 国模无码大尺度一区二区三区| 国产综合久久久久久久久久久久| 国产精品一区二区免费不卡 | 国产视频亚洲色图| 亚洲国产成人一区二区三区| 亚洲欧洲日韩在线| 尤物在线观看一区| 三级欧美韩日大片在线看| 久久成人免费网| 懂色av噜噜一区二区三区av | 欧美性大战xxxxx久久久| 欧美日韩免费高清一区色橹橹| 日韩一区二区麻豆国产| 久久综合九色综合久久久精品综合 | 国产99精品视频| 91理论电影在线观看| 亚洲国产一区二区三区高清| 国产精品久久久久久久免费软件|