在Java開發(fā)中,單例模式是常見的一種設(shè)計(jì)模式,它可以保證一個(gè)類只有一個(gè)實(shí)例,并且提供了一個(gè)全局的訪問點(diǎn)。在單例模式中,懶漢式和餓漢式是兩種常見的實(shí)現(xiàn)方式。
懶漢式
public class LazySingleton { private static LazySingleton instance; private LazySingleton() {} public static synchronized LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }
懶漢式是在第一次使用時(shí)才會(huì)實(shí)例化對象,它的優(yōu)點(diǎn)是節(jié)省了內(nèi)存空間,但缺點(diǎn)是可能存在線程安全問題。在多線程的情況下,可能會(huì)出現(xiàn)多個(gè)線程同時(shí)訪問getInstance()方法,導(dǎo)致重復(fù)實(shí)例化對象。
餓漢式
public class EagerSingleton { private static final EagerSingleton instance = new EagerSingleton(); private EagerSingleton() {} public static EagerSingleton getInstance() { return instance; } }
餓漢式是在類加載時(shí)就已經(jīng)實(shí)例化對象,它的優(yōu)點(diǎn)是不存在線程安全問題,但缺點(diǎn)是可能造成內(nèi)存浪費(fèi)。如果該對象很長時(shí)間內(nèi)沒有被使用,那么就會(huì)一直占據(jù)內(nèi)存空間。
因此,選擇懶漢式還是餓漢式需要根據(jù)具體的情況進(jìn)行考慮,鑒于懶漢式可能存在線程安全問題,可以采用雙重檢驗(yàn)鎖的方式來保證線程安全,代碼如下:
public class DoubleCheckSingleton { private volatile static DoubleCheckSingleton instance; private DoubleCheckSingleton() {} public static DoubleCheckSingleton getInstance() { if (instance == null) { synchronized (DoubleCheckSingleton.class) { if (instance == null) { instance = new DoubleCheckSingleton(); } } } return instance; } }
雙重檢驗(yàn)鎖模式可以在保證線程安全的同時(shí),盡可能地減少了鎖的使用,提高了性能。