上篇部落格針對快取用個futuretask
來進行處理來解決兩個執行緒可能計算出來同樣的值的問題。
在上篇部落格中的實現幾乎是完美的,它能夠表現出非常好的併發性,如果結果計算出來則立即返回,如果其他執行緒在計算該結果,那麼新的執行緒將一直等待這個結果被計算出來。這樣其實也沒有徹徹底底的解決兩個執行緒計算出相同的值,但是這種情況出現的概率降的非常低了。
其實這裡主要還會出現這種情況原因是compute
方法中沒有進行檢查再執行的操作,所以還會出現兩個執行緒同樣值的情況。
這時候需要在memoizer中加入原子操作來解決,具體**:
public inte***ce computable
public class expensivefunction implements computalbe
}public class memoizer4implements computable
public v compute(a arg) throws interruptedexception
};futuretaskft=new futuretask(eval);
cache.putifabsent(arg,ft);
if(f==null)
s} trycatch(executionexception e)
}}
其實問題是出現在compute
方法中的
if沒有進行原子操作,所以對
ft進行乙個二次判斷來保持原子操作。
到此位置整個快取的demo
做完了,通過這樣乙個例子,能夠充分了解同步容器和併發容器的區別和使用。
併發基礎 11 併發 容器
要實現乙個執行緒安全的佇列有兩個方式 一種是使用阻塞演算法,另一種是使用非阻塞演算法。阻塞演算法 使用阻塞演算法的佇列可以用乙個鎖 入隊和出隊同一把鎖 或兩把鎖 入隊和出隊用不同的鎖 來實現。非阻塞的實現方式則可以使用迴圈cas的方式來實現。concurrentlinkedqueue非阻塞執行緒安全...
併發程式設計9 併發容器
解決併發情況下的容器執行緒安全問題 譬如 vector,hashtable,都是給予同步鎖實現的 concurrent包下的類,大部分都是使用系統底層的實現,類似於native public class test09 latch.countdown for thread t arr try catc...
同步容器與併發容器
同步容器 可以簡單地理解為通過synchronized來實現同步的容器,如果有多個執行緒呼叫同步容器的方法,它們將會序列執行。比如vector,hashtable 早起jdk的一部分 及collections.synchronized 等方法返回的容器。可以通過檢視vector,hashtable等...