设计模式之单例模式实践
Posted itworkerlittlewrite
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之单例模式实践相关的知识,希望对你有一定的参考价值。
概念
单例模式即一个JVM内存中只存在一个类的对象实例
分类
1、懒汉式
类加载的时候就创建实例
2、饿汉式
使用的时候才创建实例
当然还有其他的生成单例的方式,双重校验锁,枚举和静态内部类,文中会有介绍
实践
懒汉式
1)线程不安全,不可用
1 public class Singleton { 2 3 private static Singleton instance; 4 5 private Singleton (){} 6 7 8 9 public static Singleton getInstance() { 10 11 if (instance == null) { 12 13 instance = new Singleton(); 14 15 } 16 17 return instance; 18 19 } 20 21 }
2)线程安全,同步方法,效率低,不推荐
public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
3)线程不安全,会产生多个实例,不可用
public class Singleton { private static Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { singleton = new Singleton(); } } return singleton; } }
饿汉式无线程安全问题,不能延迟加载,影响系统性能
4)
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
5)
public class Singleton { private static Singleton instance = null; static { instance = new Singleton(); } private Singleton (){} public static Singleton getInstance() { return instance; } }
6)双重校验锁,线程安全,推荐使用
public class Singleton { private static volatile Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
7)静态内部类,线程安全,主动调用时才实例化,延迟加载效率高,推荐使用
public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }
8)枚举类型,无线程安全问题,避免反序列化创建新的实例,很少使用
public enum Singleton { INSTANCE; public void whateverMethod() { } }
注意事项
1、考虑多线程问题
2、单例类构造方法要设置为private类型禁止外界new创建
private Singleton() {}
3、如果类可序列化,考虑反序列化生成多个实例问题,解决方案如下
private Object readResolve() throws ObjectStreamException { // instead of the object we‘re on, return the class variable INSTANCE return INSTANCE; }
使用场景
1、工具类对象
2、系统中只能存在一个实例的类
3、创建频繁或又耗时耗资源且又经常用到的对象
另外,spring容器中的实例默认是单例饿汉式类型的,即容器启动时就实例化bean到容器中,当然也可以设置懒汉式defalut-lazy-init="true"为延迟实例化,用到时再实例化。
以上是关于设计模式之单例模式实践的主要内容,如果未能解决你的问题,请参考以下文章