天天看點

java 單例 餓漢_java單例 餓漢式

構造方法裡Thread.sleep(10),模拟下類的構造過程,用多線程去getInstance(),再print(m_instance),就會發現位址值不一樣了,說明構造了多個對象,這麼寫就是防止這種情況。其實也并不需要用DCL這種方式,餓漢模式就能避免這種情況。######嗯嗯 sleep() 要的就是這個 非常感謝######個人是這麼了解的,假如有兩個線程 A,B同時調用 getInstance方法,當A線程運作到代碼第6行時,時間片被撤出,B線程運作getInstance方法,拿到鎖之後,對變量進行指派,這是為了防止多線程的情況下,會造成建立多個對象。######  private static LazySingleton m_instance = new LazySingleton(); 這樣簡單

######嗯 餓漢式單例和帶有同步機制的懶漢式單例都應該沒問題######如果初始化開銷大,這種方式就不太好。但是一般的,這種方式比較好。我也喜歡這種方式。###### 對的 可以參考《Java concurrency in practice》16.2.4節 如果必須實作lazy initialization,可以利用JVM的lazy class loading機制。 ######額 我找找這本書######寫兩個線程,打個斷點不就可以觀察了嗎?或者在 if(m_instance == null)後面sleep()幾秒,如果沒有雙重檢查,你就會看到兩個線程分别分别産生了不同的對象,二者拿到的對象不是同一個,是以不能保證單例######sleep正中靶心###### Intuitively, this algorithm seems like an efficient solution to the problem. However, this technique has many subtle problems and should usually be avoided. For example, consider the following sequence of events:

Thread A notices that the value is not initialized, so it obtains the lock and begins to initialize the value. Due to the semantics of some programming languages, the code generated by the compiler is allowed to update the shared variable to point to a partially constructed object before A has finished performing the initialization. For example, in Java if a call to a constructor has been inlined then the shared variable may immediately be updated once the storage has been allocated but before the inlined constructor initializes the object.[4] Thread B notices that the shared variable has been initialized (or so it appears), and returns its value. Because thread B believes the value is already initialized, it does not acquire the lock. If B uses the object before all of the initialization done by A is seen by B (either because A has not finished initializing it or because some of the initialized values in the object have not yet percolated to the memory B uses (cache coherence)), the program will likely crash.(wiki) ######嗯嗯 就是這個意思 本來很暈 看了大家的回答 确實這段代碼在java中就是錯誤的