设计模式--单例模式


  单例模式概念
          单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以
   确保系统中一个类只产生一个实例。
  
  好处:
           对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级
   对象而言,是非常可观的一笔系统开销
           由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,
    缩短GC停顿时间


饿汉

//饿汉
//无法对instance实例进行延迟加载
public class Hungry {
	private static final Hungry hungry = new Hungry();


	private Hungry() {
		System.out.println("Single Hungry is create ");
	}


	public static Hungry getHungrySingleton() {
		return hungry;
	}


	public static void createString() {
		System.out.println("createString in singleton");
	}


	public static void main(String[] args) {
		Hungry.createString();
	}
}
懒汉
//懒汉
//在多线程并发下这样的实现是无法保证实例是唯一的/线程不安全
//创建多线程,会发现hashCode值是不一样的
//System.out.println(Lazy.getInstance.hashCode());
public class Lazy {
	private static Lazy lazy;

	private Lazy() {
	}

	public static Lazy getInstance() {
		// 第一次调用的时候会被初始化
		if (lazy == null) {
			lazy = new Lazy();
		}
		return lazy;
	}

	public static void createString() {
		System.out.println("createString in singleton");
	}

	public static void main(String[] args) {
		Lazy.createString();
	}
}

懒汉线程安全

//懒汉线程安全
//相比懒汉模式是线程安全的,但是有性能上的不足
//优化:DCL 双重检查锁模式
public class LazySafetSingleton {
	private static LazySafetSingleton lazySafetSingleton;

	private LazySafetSingleton() {
	}

	// 方法中声明synchronized关键字
	public static synchronized LazySafetSingleton getInstance() {
		if (lazySafetSingleton == null) {
			lazySafetSingleton = new LazySafetSingleton();
		}
		return lazySafetSingleton;
	}

	// 同步代码块实现
	public static LazySafetSingleton getInstance1() {
		synchronized (LazySafetSingleton.class) {
			if (lazySafetSingleton == null) {
				lazySafetSingleton = new LazySafetSingleton();
			}
			return lazySafetSingleton;
		}
	}
	public static void createString() {
		System.out.println("createString in singleton");
	}
	
	public static void main(String[] args) {
		LazySafetSingleton.createString();
	}
}

DCL

//Dcl 双重检查锁模式  性能和安全会比懒汉和懒汉线程好些
public class DclSingleton {
	//添加volatile禁止jvm的指令重排序优化
	private static volatile DclSingleton dclSingleton = null;

	private DclSingleton() {
	}
    //两次检查dclSingleton是否为null
	public static DclSingleton getInstance() {
		// 避免不必要的同步
		if (dclSingleton == null) {
			// 同步
			synchronized (DclSingleton.class) {
				// 在第一次调用时初始化
				if (dclSingleton == null) {
					dclSingleton = new DclSingleton();
					//dclSingleton = new DclSingleton();这里不是原子操作,那么jvm在检验的时候
					//1.给instance分配内存控件,
					//2.调用Dclsingleton的构造方法,初始化变量,
					//3.将dclSingleton指向jvm分配的内存空间,
					//但jvm的即使编译器中存在指令重排序的优化,以上的步骤不一定会按照步骤走,
					//这时候就会造成线程不安全,解决方法是将dclSingleton加上volatile
				}
			}
		}
		return dclSingleton;
	}
}

静态内部类的单例模式

//静态内部类的单例模式   既能延时加载也是线程安全的
//jvm本身机制保证了线程安全/没有性能缺陷
/*
 * jvm提供的同步控制,即static和final关键字
 * static保证数据在内存中是独一份的
 * final初始化后无法被修改
 * */
public class StaticInnerSingleton {
   private StaticInnerSingleton(){}
   
   public static StaticInnerSingleton getInstance(){
	   return SingletonHolder.sInstance;
   }
   
   //静态内部类
   private static class SingletonHolder{
	   private static final StaticInnerSingleton sInstance=new StaticInnerSingleton();
   }
}

枚举

//枚举方式的单例模式
//写法简单/线程安全
//不写实例方法的话,默认枚举的实例创建是实例安全的,如果要添加变量和实例方法需要注意线程安全。
public enum EnumSingleton {
	//定义一个枚举元素,它就是Singleton的一个实例
	INSTANCE;
	
	public void doSomeThing(){
		//do something...
	}
  
}
  饿汉:无法对instance实例进行延迟加载
  懒汉:多线程并发情况下无法保证实例的唯一性
  懒汉线程安全:使用synchronized导致性能缺陷
  DCL:JVM即使编译器的指令重排序
  静态内部类/枚举:延迟加载/线程安全/性能优势   //推荐
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值