天天看點

單例模式-懶漢式的一次多線程Debug

單例模式要要點就是一個類隻會存在一個執行個體,要想達到這種效果,最重要的就是将構造方法設定為私有,然後通過static的方法來擷取對象。

單例模式-懶漢式的一次多線程Debug

上述設計并不線程安全,因為在<code>lazysingleton = new lazysingletion()</code>這一步可能會發送線程的切換,導緻出現多個lazysingletion對象。

可以通過多線程debug來測試。

線程類:

單例模式-懶漢式的一次多線程Debug

測試類:

單例模式-懶漢式的一次多線程Debug

在多線程debug時需要在斷點處勾選<code>thread</code>。

單例模式-懶漢式的一次多線程Debug

之後開始debug。

單例模式-懶漢式的一次多線程Debug

開始時建立了兩個lazythread線程對象。

單例模式-懶漢式的一次多線程Debug

可以看到目前有三個程序,<code>main</code>,<code>thread-0</code>,<code>thread-1</code>。

我們切換至<code>thread-0</code>将此線程執行到lazysingleton對象建立處。

單例模式-懶漢式的一次多線程Debug

此時lazysingleton還沒有執行個體化,為null,是以<code>thread-1</code>也可以通過if判斷進入其中。我們将<code>thread-1</code>線程也執行至此處。

單例模式-懶漢式的一次多線程Debug

接下來的順序就無所謂了,兩個線程都會去自己執行個體化lazysingleton對象。

單例模式-懶漢式的一次多線程Debug

執行完成後通過列印發現lazysingleton對象其實不是同一個。

如果我們正常運作呢?

單例模式-懶漢式的一次多線程Debug

可以發現大部分情況下都會時同一個lazysingleton對象。

為了保證線程安全性,可以通過<code>synchronized</code>來修飾getinstance方法。

至于這種情況下的調試,在<code>thread-0</code>進入<code>synchronized</code>塊中時,切換至<code>thread-1</code>會發現無法進入。