日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

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

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

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

使用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)境中這會嚴(yán)重影響速度。從而導(dǎo)致使用緩存可能比不使用緩存需要的時間更長。

使用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; }}

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

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

下面我們使用FutureTask來進(jìn)行改寫。

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)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久这里只有| 精品一区二区三区的国产在线观看 | 国产视频一区在线观看一区免费| 黄色不卡一区| 日韩中文字幕av电影| 日韩和欧美一区二区| 久久99精品久久久久久园产越南| 国产精品久久久久久久久久齐齐| 麻豆91小视频| 亚洲va中文在线播放免费| 国产高清一区| 日韩欧美精品一区二区综合视频| 国产精品宾馆| 99久久亚洲精品蜜臀| 丝袜美腿成人在线| 国产精品多人| 激情婷婷亚洲| 日韩二区三区在线观看| 久久在线91| 一本色道精品久久一区二区三区| 日韩高清欧美激情| 欧美www视频在线观看| 婷婷成人在线| 四虎国产精品免费久久| 久久中文字幕导航| 91久久视频| 国产精品成人国产| 中日韩男男gay无套| 久久中文字幕一区二区| 亚洲一区不卡| 国产一区二区视频在线看| 六月丁香综合| 精品国产第一福利网站| 亚洲a级精品| 成人日韩在线观看| 日韩高清不卡在线| 久久激情婷婷| 久久激情av| 亚洲国产成人精品女人| 欧美国产先锋| 免费久久99精品国产| 色爱综合网欧美| 亚洲1区在线观看| 91精品蜜臀一区二区三区在线| 日韩av中文字幕一区| 欧美va天堂| 黄色精品视频| 天堂av一区| 欧美亚洲国产一区| 精品午夜视频| 青青国产精品| 午夜国产一区二区| 欧美a级一区二区| 免费在线观看日韩欧美| | 美女高潮久久久| 国产亚洲一区在线| 欧美精选视频一区二区| 麻豆精品蜜桃视频网站| 亚洲一区导航| 黄色国产精品| 青青久久av| 国产一区福利| 国产高清精品二区| 日韩1区2区3区| 欧美日韩免费观看一区=区三区| 国产精品伦一区二区| 男人的天堂亚洲一区| 私拍精品福利视频在线一区| 精品中文在线| 久久不卡日韩美女| 国产欧美日韩亚洲一区二区三区| 亚洲欧洲国产精品一区| 久久xxxx精品视频| 中文日韩在线| 日韩亚洲精品在线| 极品日韩av| 亚洲网站视频| 激情欧美一区| 精品欧美激情在线观看| 欧美成人精品| 欧美国产美女| 国内精品麻豆美女在线播放视频| 国产精品亲子伦av一区二区三区| 欧美一区二区三区久久精品| 日韩手机在线| 日韩精品免费一区二区夜夜嗨 | 久久麻豆视频| 国产精品久久久久久模特| 欧美日韩18| 欧美亚洲一区二区三区| 日韩高清在线不卡| 亚洲欧洲美洲国产香蕉| 亚洲理论在线| 69堂精品视频在线播放| 久久精品超碰| 久久免费精品| 国产在线观看www| 午夜精品成人av| 在线精品视频在线观看高清| 香蕉国产精品| 久久不射中文字幕| 日韩动漫一区| 欧美黑人巨大videos精品| 国产精品久久久久久久久久10秀 | 日韩区欧美区| 国产精品亚洲人成在99www| 久久av影视| 韩国久久久久久| 91精品福利| 日韩一区免费| 精品在线网站观看| 欧美亚洲激情| 午夜亚洲福利| 国产精品扒开腿做爽爽爽软件| 久久精品人人| 久久精品在线| 亚洲视频电影在线| 日本不卡一区二区三区| 你懂的国产精品| 欧美日韩视频免费观看| 精品91久久久久| 欧美久久久网站| 日韩国产欧美| 日韩中文字幕不卡| 麻豆精品在线播放| 91超碰国产精品| 国产欧美69| 伊人久久大香线蕉av不卡| 亚洲精品无吗| 国产精品久久久久久久免费观看 | 综合欧美亚洲| 麻豆一区二区三| 国产99久久久国产精品成人免费| 一区二区三区国产在线| 国产一区一一区高清不卡| 狠狠久久婷婷| 免费在线亚洲欧美| 伊人久久亚洲热| 久久精品伊人| 日韩影院免费视频| 韩国一区二区三区视频| 免费成人在线影院| 国内精品伊人| 亚洲天堂日韩在线| 97精品国产| 精品一区二区三区中文字幕| 美腿丝袜在线亚洲一区| 欧美日韩一区二区综合| 日本免费在线视频不卡一不卡二| 麻豆成全视频免费观看在线看| 欧美日韩高清| 国产毛片久久久| 欧美不卡视频| 精品一区二区三区中文字幕视频 | 97久久亚洲| 久久国产中文字幕| 午夜精品影视国产一区在线麻豆| www在线观看黄色| 亚洲精品极品| 欧美日韩国产一区二区三区不卡| 另类小说一区二区三区| 视频一区二区三区中文字幕| 国产成人精品福利| 91欧美日韩在线| 亚洲少妇一区| 久久婷婷一区| 国产精品福利在线观看播放| 青青国产91久久久久久| 国产精品毛片一区二区三区| 在线天堂中文资源最新版| 欧美日韩 国产精品| 欧美 日韩 国产精品免费观看| 久久久久黄色| 日韩综合一区二区| 欧美肉体xxxx裸体137大胆| 精品一区视频| 国产欧美88| 日韩精品一级| 亚洲欧美久久| 久久在线视频免费观看| 日韩av专区| 久久久久亚洲精品中文字幕| 日韩av中文字幕一区二区| 免费美女久久99| 欧美在线资源| 亚洲国产综合在线看不卡| 久久不见久久见免费视频7| 日韩一区精品字幕| 最新国产拍偷乱拍精品| 天堂日韩电影| 色网在线免费观看| 综合日韩av| 91av亚洲| 在线一区视频观看| 亚洲一区资源| sm久久捆绑调教精品一区| 国产精品毛片aⅴ一区二区三区| 亚洲日产国产精品| 蜜桃一区二区三区在线观看|