单例模式八个例子#yyds干货盘点#

Posted Java4ye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式八个例子#yyds干货盘点#相关的知识,希望对你有一定的参考价值。

参考大神Tom的《Spring 5核心原理与30个类手写实战-谭勇德》

使用场景

饿汉式

在类加载的时候就<font style=color:#0099ff>立即初始化</font>,并且创建单例对象,属于<font style=color:#0099ff>线程安全</font>

package com.example.demo.singleton;

*/***

 ** 饿汉式*

 *** *@author* *Java4ye*

 ** @date 2020/9/6 8:19*

 **/*

public class HungrySingleton 

  private static final HungrySingleton hungry=new HungrySingleton();

  private HungrySingleton() 

  

  public static HungrySingleton getInstance()

    return hungry;

  


懒汉式

package com.example.demo.singleton;

*/***

 ** 懒汉式*

 *** *@author* *Java4ye*

 ** @date 2020/9/6 8:19*

 **/*

public class LazySingleton 

  private static LazySingleton instance=null;

  private LazySingleton()

  public static LazySingleton getInstance()

    if(instance==null)

      instance=new LazySingleton();

    

    return instance;

  

双重检查锁模式

懒汉式是线程不安全的,需要加锁

package com.example.demo.singleton;

*/***

 ** 双重检查锁*

 *** *@author* *Java4ye*

 ** @date 2020/9/6 8:19*

 **/*

public class LazyDoubleCheckSingleton 

  private static LazyDoubleCheckSingleton lazyDoubleCheckMode=null;

  private LazyDoubleCheckSingleton()

  public static LazyDoubleCheckSingleton getInstance()

    if (lazyDoubleCheckMode==null)

      synchronized(LazyDoubleCheckSingleton.class)

       if (lazyDoubleCheckMode==null)

          lazyDoubleCheckMode= new LazyDoubleCheckSingleton();

        

      

    

    return lazyDoubleCheckMode;

  


静态内部类模式

package com.example.demo.singleton;

*/***

 ** 静态内部类模式*

 ** 这种形式兼顾饿汉式单例模式的内存浪费问题和 synchronized 的性能问题*

 ** 加载静态变量,方法,不包括这个静态内部类*

 ** 被外部类调用的时候内部类才会加载*

 ***

 *** *@author* *Java4ye*

 ** @date 2020/9/6 9:12*

 **/*

public class LazyInnerClassSingleton 

  public static LazyInnerClassSingleton getInstance() 

    return InnerLazyHolder.LAZY;

  

  private static class InnerLazyHolder 

    private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();

  

  */***

   ** 防止反射创建*

   **/*

  private LazyInnerClassSingleton() 

    if (InnerLazyHolder.LAZY != null) 

      throw new RuntimeException("不允许创建多个实例");

    

  


序列化模式

package com.example.demo.singleton;

import java.io.Serializable;

*/***

 ** 序列化模式*

 ***

 *** *@author* *Java4ye*

 ** @date 2020/9/6 21:59*

 **/*

public class SerializableSingleton implements Serializable 

  private static final long serialVersionUID = 7018585554862336578L;

  private SerializableSingleton() 

  

  private static final SerializableSingleton INSTANCE = new SerializableSingleton();

  public static SerializableSingleton getInstance() 

    return INSTANCE;

  

  */***

   *objectInputStream中通过这个hasReadResolveMethod去判断有没有该方法,有的话反序列化会去调用该方法*

   *返回类型必须是Object*

   **/*

  private Object readResolve() 

    return INSTANCE;

  


注册式单例模式

枚举式

package com.example.demo.singleton;

*/***

 ** 注册式单例模式又称为登记式单例模式 就是将每一个实例都登记到某一个地方,使用唯一的标识 。注册式单例模式有两种:一种为枚举式单例,另一为容器式单例模式*

 ** 注册式单例模式之枚举式*

 *** *@author* *Java4ye*

 ** @date 2020/9/6 23:18*

 **/*

public enum EnumSingleton 

  */***

   ** 单例*

   ** \\*/*

  INSTANCE;

  private Object data;

  public Object getData() 

    return data;

  

  public void setData(Object data) 

    this.data = data;

  

  public static EnumSingleton getInstance()

    return INSTANCE;

  


容器式

package com.example.demo.singleton;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

*/***

 ** 注册式单例模式又称为登记式单例模式 就是将每一个实例都登记到某一个地方,使用唯一*

 ** 的标识 。注册式单例模式有两种:一种为枚举式单例,另一为容器式单例模式*

 ** 注册式单例模式之容器式*

 *** *@author* *Java4ye*

 ** @date 2020/9/9 7:16*

 **/*

public class ContainerSingleton 

  private ContainerSingleton()

  private static final Map<String,Object> ioc=new ConcurrentHashMap<>();

  public static Object getBean(String className)

    synchronized (ioc)

      if (!ioc.containsKey(className))

        Object obj=null;

        try 

          obj = Class.forName(className).newInstance();

          ioc.put(className,obj);

         catch (InstantiationException | ClassNotFoundException | IllegalAccessException e) 

          e.printStackTrace();

        

        return obj;

      else

        return ioc.get(className);

      

    

  

线程单例实现 Thread Local

package com.example.demo.singleton;

*/***

 ** 线程单例实现 Thread Local*

 ** 确保每一个线程只有一个实例对象*

 *** *@author* *Java4ye*

 ** @date 2020/9/9 7:31*

 **/*

public class ThreadLocalSingleton 

  private ThreadLocalSingleton() 

  

  private static final ThreadLocal<ThreadLocalSingleton> threadLocal =

      ThreadLocal.withInitial(ThreadLocalSingleton::new);

  public static ThreadLocalSingleton getInstance()

    return threadLocal.get();

  


测试

先简单测试下这个 【懒汉式线程不安全版本】 和 【反射破坏单例】 这两种模式。。。其他几个写在下篇博客啦

以上是关于单例模式八个例子#yyds干货盘点#的主要内容,如果未能解决你的问题,请参考以下文章

单例模式 --- 生产环境怎么写#yyds干货盘点#

#yyds干货盘点# 关键字: volatile详解

#yyds干货盘点# 设计模式之代理模式:动态代理

#yyds干货盘点# 100个 Unity小知识点 | Unity中常用的几种单例写法

#yyds干货盘点# 100个 Unity小知识点 | Unity中常用的几种单例写法

#yyds干货盘点# 设计模式之代理模式:静态代理