Java8簡單的本地緩存實現


這里我將會給大家演示用ConcurrentHashMap類和lambda表達式實現一個本地緩存。因為Map有一個新的方法,在key為Null的時候自動計算一個新的value值。非常適合實現cache。來看下代碼:

public static void main(String[] args) { for (int i = 0; i < 10; i++) System.out.println( "f(" + i + ") = " + fibonacci(i)); } static int fibonacci(int i) { if (i == 0) return i; if (i == 1) return 1; System.out.println("Calculating f(" + i + ")"); return fibonacci(i - 2) + fibonacci(i - 1); }

當然,這種方式很傻瓜。即使對於一個非常小的數,例如fibonacci(5),上面的代碼也會打印出很多行,而且都是在進行重復計算,輸出如下(只截取一部分):

Calculating f(6) Calculating f(4) Calculating f(2) Calculating f(3) Calculating f(2) Calculating f(5) Calculating f(3) Calculating f(2) Calculating f(4) Calculating f(2) Calculating f(3) Calculating f(2) f(6) = 8

我們想要做的就是創建一個緩存,用來計算斐波那契數列。最直接的方法就是在緩存中存放所有的value值。cache的創建如下:

static Map<Integer, Integer> cache = new HashMap<>()

(譯者注:這種寫法在java8中是允許的)

聲明cache之后,通過Map.computeIfAbsent() 方法,可以在key所對應的value值不存在的情況下,計算一個新的value值。超高速緩存(Caching)!由於這個方法是自動執行的,而且我們使用了 ConcurrentHashMap對象,這個緩存是線程安全的,不需要手動的去寫同步方法。另外,它不僅僅可以處理斐波那契額數列,在其他地方也可以被重復使用。

不過現在,我們看看如何在fibonacci()方法中使用緩存。

static int fibonacci(int i) { if (i == 0) return i; if (i == 1) return 1; return cache.computeIfAbsent(i, (key) -> fibonacci(i - 2) + fibonacci(i - 1)); }

瞧瞧。不能比這個再簡單了吧。想要證明嗎?好吧,我們在每次計算一個新值的時候,加上些日志:

static int fibonacci(int i) { if (i == 0) return i; if (i == 1) return 1; return cache.computeIfAbsent(i, (key) -> { System.out.println( "Slow calculation of " + key); return fibonacci(i - 2) + fibonacci(i - 1); }); }

程序輸出如下:

f(0) = 0 f(1) = 1 Slow calculation of 2 f(2) = 1 Slow calculation of 3 f(3) = 2 Slow calculation of 4 f(4) = 3 Slow calculation of 5 f(5) = 5 Slow calculation of 6 f(6) = 8 Slow calculation of 7 f(7) = 13 Slow calculation of 8 f(8) = 21 Slow calculation of 9 f(9) = 34

在Java7下又如何實現呢?

這樣代碼就會多一些,我們可以使用double-checked locking來實現:

static int fibonacciJava7(int i) { if (i == 0) return i; if (i == 1) return 1; Integer result = cache.get(i); if (result == null) { synchronized (cache) { result = cache.get(i); if (result == null) { System.out.println( "Slow calculation of " + i); result = fibonacci(i - 2) + fibonacci(i - 1); cache.put(i, result); } } } return result; }

注:你實際的解決方案很可能會用到Guava Caches。

總結:Lambdas 表達式是Java8中非常重要的一部分。同時我們不要忘記那些新添加到庫中的,可以和Lambdas 配合使用的特性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM