乐趣区

Java 23种设计模式 之单例模式 7种实现方式

一、懒汉式(线程不安全)
package com.java.singleton;

// 懒汉式 线程不安全
public class LazySingleton {

// 私有构造方法 只允许在内部进行实例的创建
private LazySingleton() {
}

private static LazySingleton instance = null;

// 创建实例
public static LazySingleton getInstance() {

if (instance == null) {
instance = new LazySingleton();
}

return instance;
}
}
二、懒汉式(线程安全)
package com.java.singleton;

// 懒汉式 线程安全
public class SynchronizedLazySingleton {

// 私有构造方法 只允许在内部进行实例的创建
private SynchronizedLazySingleton() {
}

private static SynchronizedLazySingleton instance = null;

// 创建实例 线程安全
public static synchronized SynchronizedLazySingleton getInstance() {

if (instance == null) {
instance = new SynchronizedLazySingleton();
}

return instance;
}

}
三、饿汉式(线程安全)
package com.java.singleton;

// 饿汉式
public class HungrySingleton {

// 私有构造方法 只允许在内部进行实例的创建
private HungrySingleton() {
}

// 静态初始化 由 JVM 保证线程安全
private static HungrySingleton instance = new HungrySingleton();

// 创建实例
public static HungrySingleton getInstance() {

return instance;
}

}
四、缓存实现(线程不安全)
package com.java.singleton;

import java.util.HashMap;
import java.util.Map;

// 线程不安全 缓存实现
public class CacheSingleton {

// 私有构造方法 只允许在内部进行实例的创建
private CacheSingleton() {
}

// 构造缓存容器
private static Map<String, CacheSingleton> map = new HashMap<>();

// 构造默认的存放 key
private static final String DEFAULT_KEY = “Cache”;

// 创建实例
public static CacheSingleton getInstance() {

// 先从缓存中取 没有就创建并放入缓存 有就返回
CacheSingleton instance = (CacheSingleton) map.get(DEFAULT_KEY);

if (instance == null) {

instance = new CacheSingleton();
map.put(DEFAULT_KEY, instance);
}

return instance;
}

}
五、双重检查加锁(懒汉式 线程安全的进一步优化)
package com.java.singleton;

// 双重检查加锁 懒汉式在方法上加 synchronized 的进一步优化
public class DoubleCheckedLockingSingleton {

// 私有构造方法 只允许在内部进行实例的创建
private DoubleCheckedLockingSingleton() {
}

//volatile 修饰的变量不会被本地线程缓存 对该变量的读写直接作用于共享内存 类似于互斥锁
private volatile static DoubleCheckedLockingSingleton instance = null;

// 创建实例
public static DoubleCheckedLockingSingleton getInstance() {

if (instance == null) {

synchronized (DoubleCheckedLockingSingleton.class) {

if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}

}

return instance;
}

}
六、Lazy Initialization Holder Class 实现单例
package com.java.singleton;

// 静态内部类 Lazy Initialization Holder Class
public class LazyInitializationHolderClassSingleton {

// 私有构造方法 只允许在内部进行实例的创建
private LazyInitializationHolderClassSingleton() {
}

/*
* 静态成员式内部类 该内部类的实例对象与外部类的实例无绑定关系
* 有且只有在 LazyInitializationHolder 被调用 instance 时 在会对对象实例进行装载
* 从而实现延时加载
*/
private static class LazyInitializationHolder {

/*
* 静态初始化器 由 JVM 保证线程安全
*
*/
private static LazyInitializationHolderClassSingleton instance = new LazyInitializationHolderClassSingleton();
}

// 创建实例
public static LazyInitializationHolderClassSingleton getInstance() {

return LazyInitializationHolder.instance;
}

}
七、枚举实现单例
package com.java.singleton;

public enum EnumSingleton {

// 枚举类的每个元素 都代表一个单例
uniqueEnumSingleton;

public void method() {

System.out.println(“EnumSingleton”+uniqueEnumSingleton.hashCode());
}

}
八、测试类
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\t” + CacheSingleton.getInstance());
}
System.out.println(“——————————————————————-\n”);
}

@Test
public void testDoubleCheckedLockingSingleton() {

for (int i = 0; i < 3; i++) {

System.out.println(“DoubleCheckedLockingSingleton\t” + DoubleCheckedLockingSingleton.getInstance());
}
System.out.println(“——————————————————————-\n”);
}

@Test
public void testEnumSingleton() {

for (int i = 0; i < 3; i++) {

EnumSingleton.uniqueEnumSingleton.method();
}
System.out.println(“——————————————————————-\n”);
}

@Test
public void testHungrySingleton() {

for (int i = 0; i < 3; i++) {

System.out.println(“HungrySingleton\t” + HungrySingleton.getInstance());
}
System.out.println(“——————————————————————-\n”);
}

@Test
public void testLazyInitializationHolderClassSingleton() {

for (int i = 0; i < 3; i++) {

System.out.println(“LazyInitializationHolderClassSingleton\t” + LazyInitializationHolderClassSingleton.getInstance());
}
System.out.println(“——————————————————————-\n”);
}

@Test
public void testLazySingleton() {

for (int i = 0; i < 3; i++) {

System.out.println(“LazySingleton\t” + LazySingleton.getInstance());
}
System.out.println(“——————————————————————-\n”);
}

@Test
public void testSynchronizedLazySingleton() {

for (int i = 0; i < 3; i++) {

System.out.println(“SynchronizedLazySingleton\t” + SynchronizedLazySingleton.getInstance());
}
System.out.println(“——————————————————————-\n”);
}

}
九、测试结果

退出移动版