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

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

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

    posts - 9, comments - 4, trackbacks - 0, articles - 21
    有一個很耗時的運算需要緩存其計算結果,采用備忘錄模式實現,如:
    Java代碼 
    1. public interface Computable<A, V> {  
    2.     V compute(A arg) throws InterruptedException;  
    3. }  
    4.   
    5. public class ExpensiveFunction  
    6.         implements Computable<String, BigInteger> {  
    7.     public BigInteger compute(String arg) {  
    8.         // 假設這里非常耗時...  
    9.         return new BigInteger(arg);  
    10.     }  
    11. }  


    備忘錄緩存方案一:
    Java代碼 
    1. public class Memoizer1<A, V> implements Computable<A, V> {  
    2.     @GuardedBy("this")  
    3.     private final Map<A, V> cache = new HashMap<A, V>();  
    4.     private final Computable<A, V> c;  
    5.   
    6.     public Memoizer1(Computable<A, V> c) {  
    7.         this.c = c;  
    8.     }  
    9.   
    10.     public synchronized V compute(A arg) throws InterruptedException {  
    11.         V result = cache.get(arg);  
    12.         if (result == null) {  
    13.             result = c.compute(arg);  
    14.             cache.put(arg, result);  
    15.         }  
    16.         return result;  
    17.     }  
    18. }  

    這里備忘錄的整個compute過程被同步,相當于我最原始的低效方案,


    備忘錄緩存方案二:
    Java代碼 
    1. public class Memoizer2<A, V> implements Computable<A, V> {  
    2.     private final Map<A, V> cache = new ConcurrentHashMap<A, V>();  
    3.     private final Computable<A, V> c;  
    4.   
    5.     public Memoizer2(Computable<A, V> c) { this.c = c; }  
    6.   
    7.     public V compute(A arg) throws InterruptedException {  
    8.         V result = cache.get(arg);  
    9.         if (result == null) {  
    10.             result = c.compute(arg);  
    11.             cache.put(arg, result);  
    12.         }  
    13.         return result;  
    14.     }  
    15. }  

    將線程安全性委給cache,注:這個方案的cache用了ConcurrentHashMap,它是線程安全的。

    備忘錄緩存方案三:
    Java代碼 
    1. public class Memoizer3<A, V> implements Computable<A, V> {  
    2.     private final Map<A, Future<V>> cache  
    3.             = new ConcurrentHashMap<A, Future<V>>();  
    4.     private final Computable<A, V> c;  
    5.   
    6.     public Memoizer3(Computable<A, V> c) { this.c = c; }  
    7.   
    8.     public V compute(final A arg) throws InterruptedException {  
    9.         Future<V> f = cache.get(arg);  
    10.         if (f == null) {  
    11.             Callable<V> eval = new Callable<V>() {  
    12.                 public V call() throws InterruptedException {  
    13.                     return c.compute(arg);  
    14.                 }  
    15.             };  
    16.             FutureTask<V> ft = new FutureTask<V>(eval);  
    17.             f = ft;  
    18.             cache.put(arg, ft);  
    19.             ft.run(); // call to c.compute happens here  
    20.         }  
    21.         try {  
    22.             return f.get();  
    23.         } catch (ExecutionException e) {  
    24.             throw launderThrowable(e.getCause());  
    25.         }  
    26.     }  
    27. }  

    使用Future(相當上一帖的Entry)封裝,因為這里資源獲取過程不固定(通用方案),所以使用了Callable進行回調資源獲取過程(求值),
    這個方案的 if (f == null) 不安全,特殊性可能會進行多次運算,下面的方案四解決這個問題。

    備忘錄緩存方案四(最終方案):
    Java代碼 
    1. public class Memoizer<A, V> implements Computable<A, V> {  
    2.     private final ConcurrentMap<A, Future<V>> cache  
    3.         = new ConcurrentHashMap<A, Future<V>>();  
    4.     private final Computable<A, V> c;  
    5.   
    6.     public Memoizer(Computable<A, V> c) { this.c = c; }  
    7.   
    8.     public V compute(final A arg) throws InterruptedException {  
    9.         while (true) {  
    10.             Future<V> f = cache.get(arg);  
    11.             if (f == null) {  
    12.                 Callable<V> eval = new Callable<V>() {  
    13.                     public V call() throws InterruptedException {  
    14.                         return c.compute(arg);  
    15.                     }  
    16.                 };  
    17.                 FutureTask<V> ft = new FutureTask<V>(eval);  
    18.                 f = cache.putIfAbsent(arg, ft);  
    19.                 if (f == null) { f = ft; ft.run(); }  
    20.             }  
    21.             try {  
    22.                 return f.get();  
    23.             } catch (CancellationException e) {  
    24.                 cache.remove(arg, f);  
    25.             } catch (ExecutionException e) {  
    26.                 throw launderThrowable(e.getCause());  
    27.             }  
    28.         }  
    29.     }  

    主站蜘蛛池模板: 亚洲电影在线免费观看| 老司机精品视频免费| 国产麻豆一精品一AV一免费 | 久久国产乱子伦精品免费一| 亚洲一区二区三区国产精品| 亚洲AV成人精品日韩一区 | 男男AV纯肉无码免费播放无码| 香蕉蕉亚亚洲aav综合| 在线观看免费无码视频| 久久久久久精品免费看SSS| 久久夜色精品国产噜噜亚洲AV| 亚洲va在线va天堂成人| 1024免费福利永久观看网站| 亚洲人成网站在线观看播放动漫 | 亚洲中文字幕无码av在线| 最近高清中文字幕无吗免费看| 亚洲一线产区二线产区精华| 美女视频黄是免费的网址| 亚洲日韩一区二区三区| 国产免费一区二区三区VR| 亚洲熟妇丰满多毛XXXX| 久久99精品国产免费观看| 亚洲系列国产精品制服丝袜第| 性生交片免费无码看人| 国产成人亚洲精品播放器下载| 亚洲婷婷国产精品电影人久久| WWW免费视频在线观看播放| 久久久久亚洲精品无码系列| 中文毛片无遮挡高潮免费| 亚洲精品美女久久7777777| 久久亚洲AV无码西西人体| 久久国产免费观看精品3| 日本亚洲免费无线码 | 国产jizzjizz视频全部免费| 国产伦精品一区二区免费| 亚洲美女视频网址| 日韩中文无码有码免费视频 | 叮咚影视在线观看免费完整版| 亚洲精品一卡2卡3卡三卡四卡| 免费爱爱的视频太爽了| a级毛片免费播放|