单例模式:保证在?个JVM中,该对象只有?个实例存在;
适?场景:
1、某些类创建?较频繁,对于?些?型的对象,这是?笔很?的系统开销。
2、省去了new操作符,降低了系统内存的使?频率,减轻GC压?。
3、有些类如交易所的核?交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(?如?个军队出现了多个司 令员同时指挥,肯定会乱成?团),所以只有使?单例模式,才能保证核?交易服务器独?控制整个流程。
代码:
1 public class Singleton{ 2 //持有私有静态实例,防止被引用,赋值为null,目的就是实现延迟加载 3 private static Singleton instance = null; 4 5 6 //私有构造方法,防止被实例化。 7 private Singleton(){ 8 } 9 10 //创建实例11 public static Singleton getInstance()12 {13 if (instance=null){14 instance=new Singleton();15 16 }17 return instance;18 //如果该对象被?于序列化,可以保证对象在序列化前后保持?致19 public Object readReaslove(){20 return instance;21 }22 23 }24 }
分类:
1.饿汉式:类初始化时创建单例,线程安全,但占用内存空间大,适?于占内存?的场景,否则推荐使?懒汉式延迟加载;
public class Singleton{
private static Singleton instance = new Singleton();
//构造器私有, 外部就无法new这个对象,保证一个类中只有一个实例对象
private Singleton(){}
public static Singleton newInstance(){ return instance;}}
2.懒汉式:需要单例实例的时候再创建,需要考虑线程安全(性能不太好)
1 public class Singleton{ 2 private static Singleton instance = null;//定义一个静态变量指向自己 3 private Singleton(){}//私有化构造方法 4 public static synchronized Singleton newInstance(){//加锁, 5 if (instance == null){ 6 instance = new Singleton(); 7 } 8 } 9 return instance;10 11 }
3.双重检验锁:假如两个线程A、B,A执?了if (instance == null)语句,它会认为单例对象没有创建,此时线程切到B也执?了同样的语句,B也认为单例对象没有创建,然后两个线程依次执?同步代码块,并分别创建了?个单例对象。
1 public class Singleton{ 2 private static volatile Singleton instance = null; 3 private Singleton(){} 4 public static Singleton getInstance(){ 5 if (instance == null) 6 { synchronized (Singleton.class){ 7 if (instance == null){ 8 instance = new Singleton(); 9 10 }11 }12 }13 return instance;14 }
4.静态内部类:可以同时保证延迟加载和线程安全。静态内部类单例是如何实现懒加载的呢?(懒加载 :使?的时候再创建对象)?先,我们先了解下类的加载时机。
1 public class Singleton{ 2 private Singleton(){}//私有化构造方法 3 public static Singleton getInstance(){//对外提供获取实例的公共方法 4 return InnerClass.Instance;} 5 private static class InnerClass{//定义静态内部类 6 private final static Singleton Instance=new Singleton; 7 8 } 9 10 }
5.枚举:
1 public enum Singleton{2 instance; 3 public void whateverMethod(){} 4 }