目录
单例模式定义
应用场景
Runtime.java
DefaultSingletonBeanRegistry.java
ReactiveAdapterRegistry.java
Currency.java
实现方式
1、懒汉模式
2、恶汉模式
3、静态内部类
反射打破单例模式情况
保证一个类只有一个实例,并且提供一个全局访问点
线程池、连接池等情况
标准的恶汉模式
懒汉模式
volatile的懒汉模式
带序列化和反序列化
package com.example.demo.designPattern.singleton;
/**
* @author 10450
* @description 懒汉模式
* 并发情况下,有可能
* @date 2022/9/15 13:58
*/
public class LazySingletonTest {
public static void main(String[] args){
new Thread(()->{
LazySingleton intance = LazySingleton.getSingleton();
System.out.println(intance);
}).start();
new Thread(()->{
LazySingleton intance = LazySingleton.getSingleton();
System.out.println(intance);
}).start();
new Thread(()->{
LazySafeSingleton intance = LazySafeSingleton.getSingleton();
System.out.println(intance);
}).start();
new Thread(()->{
LazySafeSingleton intance = LazySafeSingleton.getSingleton();
System.out.println(intance);
}).start();
new Thread(()->{
LazyVolatileSingleton intance = LazyVolatileSingleton.getSingleton();
System.out.println(intance);
}).start();
new Thread(()->{
LazyVolatileSingleton intance = LazyVolatileSingleton.getSingleton();
System.out.println(intance);
}).start();
}
}
/**
* 多线程不安全
*/
class LazySingleton{
private static LazySingleton instance;
private LazySingleton(){
}
public static LazySingleton getSingleton(){
if(instance==null){
try{
Thread.sleep(5000);
instance = new LazySingleton();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
return instance;
}
}
/**
* 多线程安全,但是指令重排有问题
*/
class LazySafeSingleton{
private static LazySafeSingleton instance;
private LazySafeSingleton(){
}
public static LazySafeSingleton getSingleton(){
if(instance==null){
synchronized (LazySafeSingleton.class){
if(instance==null){
try{
Thread.sleep(5000);
instance = new LazySafeSingleton();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
return instance;
}
}
/**
* 防止指令重排
*/
class LazyVolatileSingleton{
private volatile static LazyVolatileSingleton instance;
private LazyVolatileSingleton(){
}
public static LazyVolatileSingleton getSingleton(){
if(instance==null){
synchronized (LazyVolatileSingleton.class){
if(instance==null){
try{
Thread.sleep(5000);
instance = new LazyVolatileSingleton();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
return instance;
}
}
类加载的初始化节点完成实例初始化。本质就是JVM类加载机制,保证实例唯一性。
类加载过程:
package com.example.demo.designPattern.singleton;
/**
* @author 10450
* @description 恶汉模式
* 类加载的时候完成初始化
* @date 2022/9/15 14:23
*/
public class HungrySingletonTest {
public static void main(String[] args) {
System.out.println(HungrySingleton.getInstance());
System.out.println(HungrySingleton.getInstance());
}
}
class HungrySingleton{
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton(){
}
public static HungrySingleton getInstance(){
return instance;
}
}
package com.example.demo.designPattern.singleton;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @author 10450
* @description 静态内部类
* 可以防止通过反射,实现多利
* @date 2022/9/15 14:28
*/
public class InnerClassSingletonTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
new Thread(()->{
System.out.println(InnerClassSingleton.getInstance());
}).start();
new Thread(()->{
System.out.println(InnerClassSingleton.getInstance());
}).start();
//利用反射方式创建类对象打破单例模式,实现多利
Constructor declaredConstructor = InnerClassSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerClassSingleton innerClassSingleton = declaredConstructor.newInstance();
InnerClassSingleton instance = InnerClassSingleton.getInstance();
System.out.println(innerClassSingleton);
System.out.println(instance);
}
}
class InnerClassSingleton{
private static class InnerClassSingletonHolder{
private static InnerClassSingleton instance = new InnerClassSingleton();
}
private InnerClassSingleton(){
}
public static InnerClassSingleton getInstance(){
try {
System.out.println(1);
Thread.sleep(8000);
System.out.println(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return InnerClassSingletonHolder.instance;
}
}
通过反射方式创建类,可以打破单例模式,实现多例效果,
【恶汉模式】、【内部类模式】可以判断防止多例
package com.example.demo.designPattern.singleton;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* @author 10450
* @description 反射攻击
* @date 2022/9/15 15:03
*/
public class InnerClassReflexSingletonTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//单例保护防止多利情况下:
Constructor declaredConstructor = InnerClassProtectSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerClassProtectSingleton innerClassSingleton = declaredConstructor.newInstance();
InnerClassProtectSingleton instance = InnerClassProtectSingleton.getInstance();
System.out.println(innerClassSingleton);
System.out.println(instance);
}
}
/**
* 防止多例
*/
class InnerClassProtectSingleton {
private static class InnerClassSingletonHolder {
private static InnerClassProtectSingleton instance = new InnerClassProtectSingleton();
}
private InnerClassProtectSingleton() {
//添加校验,抛异常
if (InnerClassSingletonHolder.instance != null) {
throw new RuntimeException("单例模式,不运行重复创建");
}
}
public static InnerClassProtectSingleton getInstance() {
return InnerClassProtectSingleton.InnerClassSingletonHolder.instance;
}
}