摘要:一懶漢式線程不安全懶漢式線程不安全私有構(gòu)造方法只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建創(chuàng)建實(shí)例二懶漢式線程安全懶漢式線程安全私有構(gòu)造方法只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建創(chuàng)建實(shí)例線程安全三餓漢式線程安全餓漢式私有構(gòu)造方法只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建靜態(tài)初始化由保證
一、懶漢式(線程不安全)
package com.java.singleton; //懶漢式 線程不安全 public class LazySingleton { //私有構(gòu)造方法 只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建 private LazySingleton() { } private static LazySingleton instance = null; //創(chuàng)建實(shí)例 public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }
二、懶漢式(線程安全)
package com.java.singleton; //懶漢式 線程安全 public class SynchronizedLazySingleton { //私有構(gòu)造方法 只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建 private SynchronizedLazySingleton() { } private static SynchronizedLazySingleton instance = null; //創(chuàng)建實(shí)例 線程安全 public static synchronized SynchronizedLazySingleton getInstance() { if (instance == null) { instance = new SynchronizedLazySingleton(); } return instance; } }
三、餓漢式(線程安全)
package com.java.singleton; //餓漢式 public class HungrySingleton { //私有構(gòu)造方法 只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建 private HungrySingleton() { } //靜態(tài)初始化 由JVM保證線程安全 private static HungrySingleton instance = new HungrySingleton(); //創(chuàng)建實(shí)例 public static HungrySingleton getInstance() { return instance; } }
四、緩存實(shí)現(xiàn)(線程不安全)
package com.java.singleton; import java.util.HashMap; import java.util.Map; //線程不安全 緩存實(shí)現(xiàn) public class CacheSingleton { //私有構(gòu)造方法 只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建 private CacheSingleton() { } //構(gòu)造緩存容器 private static Mapmap = new HashMap<>(); //構(gòu)造默認(rèn)的存放key private static final String DEFAULT_KEY = "Cache"; //創(chuàng)建實(shí)例 public static CacheSingleton getInstance() { //先從緩存中取 沒有就創(chuàng)建并放入緩存 有就返回 CacheSingleton instance = (CacheSingleton) map.get(DEFAULT_KEY); if (instance == null) { instance = new CacheSingleton(); map.put(DEFAULT_KEY, instance); } return instance; } }
五、雙重檢查加鎖(懶漢式 線程安全的進(jìn)一步優(yōu)化)
package com.java.singleton; //雙重檢查加鎖 懶漢式在方法上加synchronized的進(jìn)一步優(yōu)化 public class DoubleCheckedLockingSingleton { //私有構(gòu)造方法 只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建 private DoubleCheckedLockingSingleton() { } //volatile 修飾的變量不會(huì)被本地線程緩存 對(duì)該變量的讀寫直接作用于共享內(nèi)存 類似于互斥鎖 private volatile static DoubleCheckedLockingSingleton instance = null; //創(chuàng)建實(shí)例 public static DoubleCheckedLockingSingleton getInstance() { if (instance == null) { synchronized (DoubleCheckedLockingSingleton.class) { if (instance == null) { instance = new DoubleCheckedLockingSingleton(); } } } return instance; } }
六、 Lazy Initialization Holder Class實(shí)現(xiàn)單例
package com.java.singleton; //靜態(tài)內(nèi)部類 Lazy Initialization Holder Class public class LazyInitializationHolderClassSingleton { //私有構(gòu)造方法 只允許在內(nèi)部進(jìn)行實(shí)例的創(chuàng)建 private LazyInitializationHolderClassSingleton() { } /* * 靜態(tài)成員式內(nèi)部類 該內(nèi)部類的實(shí)例對(duì)象與外部類的實(shí)例無綁定關(guān)系 * 有且只有在LazyInitializationHolder被調(diào)用instance時(shí) 在會(huì)對(duì)對(duì)象實(shí)例進(jìn)行裝載 * 從而實(shí)現(xiàn)延時(shí)加載 */ private static class LazyInitializationHolder { /* * 靜態(tài)初始化器 由JVM保證線程安全 * */ private static LazyInitializationHolderClassSingleton instance = new LazyInitializationHolderClassSingleton(); } //創(chuàng)建實(shí)例 public static LazyInitializationHolderClassSingleton getInstance() { return LazyInitializationHolder.instance; } }
七、枚舉實(shí)現(xiàn)單例
package com.java.singleton; public enum EnumSingleton { //枚舉類的每個(gè)元素 都代表一個(gè)單例 uniqueEnumSingleton; public void method() { System.out.println("EnumSingleton"+uniqueEnumSingleton.hashCode()); } }
八、測(cè)試類
package com.java.singleton; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class SingletonApplicationTests { @Test public void testCacheSingleton() { for (int i = 0; i < 3; i++) { System.out.println("CacheSingleton " + CacheSingleton.getInstance()); } System.out.println("------------------------------------------------------------------- "); } @Test public void testDoubleCheckedLockingSingleton() { for (int i = 0; i < 3; i++) { System.out.println("DoubleCheckedLockingSingleton " + DoubleCheckedLockingSingleton.getInstance()); } System.out.println("------------------------------------------------------------------- "); } @Test public void testEnumSingleton() { for (int i = 0; i < 3; i++) { EnumSingleton.uniqueEnumSingleton.method(); } System.out.println("------------------------------------------------------------------- "); } @Test public void testHungrySingleton() { for (int i = 0; i < 3; i++) { System.out.println("HungrySingleton " + HungrySingleton.getInstance()); } System.out.println("------------------------------------------------------------------- "); } @Test public void testLazyInitializationHolderClassSingleton() { for (int i = 0; i < 3; i++) { System.out.println("LazyInitializationHolderClassSingleton " + LazyInitializationHolderClassSingleton.getInstance()); } System.out.println("------------------------------------------------------------------- "); } @Test public void testLazySingleton() { for (int i = 0; i < 3; i++) { System.out.println("LazySingleton " + LazySingleton.getInstance()); } System.out.println("------------------------------------------------------------------- "); } @Test public void testSynchronizedLazySingleton() { for (int i = 0; i < 3; i++) { System.out.println("SynchronizedLazySingleton " + SynchronizedLazySingleton.getInstance()); } System.out.println("------------------------------------------------------------------- "); } }
九、測(cè)試結(jié)果
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73204.html
摘要:反射攻擊首先我們來看一下反射調(diào)用,以雙重檢驗(yàn)方式為例反射攻擊輸出結(jié)果是反射攻擊結(jié)果私有構(gòu)造方法被調(diào)用次私有構(gòu)造方法被調(diào)用次從結(jié)果可以看到,私有的構(gòu)造函數(shù)被調(diào)用了兩次,也就是說這樣的單例模式并不安全。 showImg(https://segmentfault.com/img/bV1fer?w=900&h=500); 保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。——艾迪生維斯理 ...
摘要:最近開展了三次設(shè)計(jì)模式的公開課,現(xiàn)在來總結(jié)一下設(shè)計(jì)模式在中的應(yīng)用,這是第一篇?jiǎng)?chuàng)建型模式之單例模式。不過因?yàn)椴恢С侄嗑€程所以不需要考慮這個(gè)問題了。 最近開展了三次設(shè)計(jì)模式的公開課,現(xiàn)在來總結(jié)一下設(shè)計(jì)模式在PHP中的應(yīng)用,這是第一篇?jiǎng)?chuàng)建型模式之單例模式。 一、設(shè)計(jì)模式簡(jiǎn)介 首先我們來認(rèn)識(shí)一下什么是設(shè)計(jì)模式: 設(shè)計(jì)模式是一套被反復(fù)使用、容易被他人理解的、可靠的代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。 設(shè)計(jì)模式不...
摘要:?jiǎn)卫J疥P(guān)注的重點(diǎn)私有構(gòu)造器線程安全延遲加載序列化和反序列化安全反射攻擊安全相關(guān)設(shè)計(jì)模式單例模式和工廠模式工廠類可以設(shè)計(jì)成單例模式。 0x01.定義與類型 定義:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn) 類型:創(chuàng)建型 UML showImg(https://segmentfault.com/img/bVbtDJ2?w=402&h=268); 單例模式的基本要素 私有的構(gòu)造方...
摘要:總之,選擇單例模式就是為了避免不一致狀態(tài),避免政出多頭。二餓漢式單例餓漢式單例類在類初始化時(shí),已經(jīng)自行實(shí)例化靜態(tài)工廠方法餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用,以后不再改變,所以天生是線程安全的。 概念: Java中單例模式是一種常見的設(shè)計(jì)模式,單例模式的寫法有好幾種,這里主要介紹兩種:懶漢式單例、餓漢式單例。 單例模式有以下特點(diǎn): 1、單例類只能有一個(gè)實(shí)例。 ...
閱讀 1751·2021-09-28 09:43
閱讀 1111·2021-09-23 11:22
閱讀 2707·2021-09-14 18:05
閱讀 1823·2019-08-30 15:52
閱讀 2812·2019-08-30 10:55
閱讀 2007·2019-08-29 16:58
閱讀 1323·2019-08-29 16:37
閱讀 3031·2019-08-29 16:25