Java執行緒安全實現懶初始化兩個方式
Java中以執行緒安全方式實現懶初始化物件有很多寫法,這裡不討論針對全域性單例場景,而是討論快取的使用場景,通常為了提高效能,我們經常透過key/物件形式將物件儲存到記憶體中,具體來說,首先我們需要檢查快取中或application作用域中是否有存在對應某個key的物件,如果不存在我們new一個物件例項放進去,這個過程是懶初始化過程,多執行緒環境為防止併發同時初始化物件例項 ,大概有兩種方式:
使用同步方式:
來自:http://www.codeproject.com/Articles/418425/Demystifying-concurrent-lazy-load-pattern
非同步的方式:
來自:http://timezra.blogspot.com/2008/04/threadsafe-lazy-instantiation-without.html
點評:雖然非同步方式從理論上看沒有鎖,應該比同步方式快,但是程式碼不是很直接,相當於加了個套子AtomicReference,這兩者還是各有其使用場景的。
Java 8引入了Lambda,見:用Java 8實現懶初始化,有些類似上面非同步方式,程式碼比較重量,關鍵是Java不是將函式作為第一等公民導致,看看Javascript中實現:
上述程式碼中getTasksFromTheServer只會執行一次。來自:NodeJS的Promise的用法
使用同步方式:
來自:http://www.codeproject.com/Articles/418425/Demystifying-concurrent-lazy-load-pattern
public IList<Product> GetProducts() { // declare local variable for cache access // and use it to be safe on sudden cache resetting List<Product> result = this.localCache; if (result == null) { lock (this.syncLock) { // recheck condition after acquiring lock // to be sure cache is not loaded while waiting for the lock result = this.localCache; if (result == null) { // it is important to first store result in local variable // and only after in cache because in between cache // might be reset result = this.LoadProductsFromDatabase(); this.localCache = result; } } } // important – return local variable and not this.localCache // above code guaranties that result will have value // on the other hand this.localCache might be reset at any time return result; } public void Reset() { // no need for any kind of locking // because our lazy load can handle resetting at any time this.localCache = null; } <p class="indent"> |
非同步的方式:
來自:http://timezra.blogspot.com/2008/04/threadsafe-lazy-instantiation-without.html
class ThreadsafeLazyGetter extends LazyGetter { private final AtomicReference<Object> lazilyCreatedObject = new AtomicReference<Object>(); @Override Object get() { final Object existingValue = lazilyCreatedObject.get(); if (existingValue != null) { return existingValue; } final Object newValue = performLongRunningInitialization(); if (lazilyCreatedObject.compareAndSet(null, newValue)) { return newValue; } return lazilyCreatedObject.get(); } } <p class="indent"> |
點評:雖然非同步方式從理論上看沒有鎖,應該比同步方式快,但是程式碼不是很直接,相當於加了個套子AtomicReference,這兩者還是各有其使用場景的。
Java 8引入了Lambda,見:用Java 8實現懶初始化,有些類似上面非同步方式,程式碼比較重量,關鍵是Java不是將函式作為第一等公民導致,看看Javascript中實現:
var tasksPromise; function getTasks() { taskPromise = taskPromise || getTasksFromTheServer(); return taskPromise; } <p class="indent"> |
上述程式碼中getTasksFromTheServer只會執行一次。來自:NodeJS的Promise的用法
[該貼被banq於2015-01-30 21:40修改過]
相關文章
- java執行緒實現方式Java執行緒
- Java多執行緒實現方式Java執行緒
- Java多執行緒之—Synchronized方式和CAS方式實現執行緒安全效能對比Java執行緒synchronized
- Java中實現執行緒的方式Java執行緒
- java執行緒建立的兩種方式Java執行緒
- Java中確保執行緒安全最常用的兩種方式Java執行緒
- Map實現執行緒安全的3種方式執行緒
- 關於多執行緒的兩種實現方式執行緒
- 【java】【多執行緒】建立執行緒的兩種常用方式(2)Java執行緒
- 單例模式——執行緒安全的兩種實現單例模式執行緒
- Java實現多執行緒的三種方式Java執行緒
- Java高併發與多執行緒(二)-----執行緒的實現方式Java執行緒
- 【Python】python 多執行緒兩種實現方式Python執行緒
- Java建立多執行緒的幾種方式實現Java執行緒
- Java之實現多執行緒的方式二:實現Runnable介面Java執行緒
- Java之實現多執行緒的方式三:實現Callable介面(結合執行緒池使用)Java執行緒
- Java中多執行緒的概述、實現方式、執行緒控制、生命週期、多執行緒程式練習、安全問題的解決...Java執行緒
- Java併發實戰一:執行緒與執行緒安全Java執行緒
- Java執行緒安全Java執行緒
- Java - 執行緒安全Java執行緒
- 面試-實現多執行緒的方式面試執行緒
- 請問如何實現兩個執行緒彼此監控?執行緒
- Java執行緒(一):執行緒安全與不安全Java執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- java執行緒實現的三種方式以及靜態代理Java執行緒
- 語音社交原始碼開發,兩個執行緒按照指定方式有序相交的實現原始碼執行緒
- 執行緒、開啟執行緒的兩種方式、執行緒下的Join方法、守護執行緒執行緒
- java執行緒安全LockJava執行緒
- Java多執行緒的實現Java執行緒
- Java 實現執行緒死鎖Java執行緒
- 【Java】【多執行緒】兩個執行緒間的通訊、wait、notify、notifyAllJava執行緒AI
- Java 多執行緒基礎(四)執行緒安全Java執行緒
- 多執行緒-匿名內部類的方式實現多執行緒程式執行緒
- Java之執行緒安全問題的3種處理方式(通過執行緒同步)Java執行緒
- Java中實現執行緒安全HashSet的幾種方法 | baeldungJava執行緒
- 【設計模式】實現執行緒安全單例模式的五種方式設計模式執行緒單例
- Java實現多執行緒詳解一 ( 繼承Thread方式 )Java執行緒繼承thread
- Java 執行緒池中的執行緒複用是如何實現的?Java執行緒