设计模式02--单例模式

一.介绍

保证某个类在程序中的实例只有一份, 该类只提供一个获得该实例的静态方法;

二. 单例模式的8种实现方式

  1. 饿汉式(静态常量)
  2. 饿汉式(静态代码块)
  3. 懒汉式(线程不安全)
  4. 懒汉式(线程安全, 同步方法)
  5. 懒汉式(线程安全, 同步代码块)
  6. Double-check双重检查
  7. 静态内部类方式
  8. 枚举方式

其中: 推荐使用1, 2, 6, 7, 8

三.代码示例

  1. 饿汉式(静态常量) [推荐]
/**
 * 单例模式1: 饿汉式-静态变量方式, 资源浪费
 * 
 * @author	Lx 
 * @version 2019年11月26日 上午11:25:01
 * @see com.lx.singleton.Singleton01
 * 
 */
public class Singleton01 {
	// 构造私有化, 防止外部new
	private Singleton01() {};
	// 私有成员静态变量
	private static final Singleton01 singleton = new Singleton01();
	// 公有静态方法
	public static Singleton01 getInstance(){
		return singleton;
	}
	
	public static void main(String[] args) {
		Singleton01 s1 = Singleton01.getInstance();
		Singleton01 s2 = Singleton01.getInstance();
		// true
		System.out.println(s1==s2);
	}
}
  1. 饿汉式(静态代码块)
/**
 * 单例模式2: 饿汉式-静态代码块方式, 资源浪费
 * 
 * @author Lx
 * @version 2019年11月26日 上午11:25:01
 * @see com.lx.singleton.Singleton02
 * 
 */
public class Singleton02 {
	// 构造私有化, 防止外部new
	private Singleton02() {};
	// 私有成员静态变量
	private static Singleton02 singleton;
	static {
		singleton = new Singleton02();
	}
	// 公有静态方法
	public static Singleton02 getInstance(){
		return singleton;
	}
	
	public static void main(String[] args) {
		Singleton02 s1 = Singleton02.getInstance();
		Singleton02 s2 = Singleton02.getInstance();
		// true
		System.out.println(s1==s2);
	}
}
  1. 懒汉式(线程不安全)
/**
 * 单例模式3: 懒汉式-线程不安全
 * 
 * @author	Lx 
 * @version 2019年11月26日 上午11:25:01
 * @see com.lx.singleton.Singleton03
 * 
 */
public class Singleton03 {
	// 构造私有化, 防止外部new
	private Singleton03() {};
	// 私有成员静态变量
	private static Singleton03 singleton = null;
	// 公有静态方法
	public static Singleton03 getInstance(){
		// 此处if判断线程不安全, 多个线程可能同时进if, 创建多次实例
		if(singleton==null) {
			singleton = new Singleton03();
		}	
		return singleton;
	}
	
	public static void main(String[] args) {
		Singleton03 s1 = Singleton03.getInstance();
		Singleton03 s2 = Singleton03.getInstance();
		// true
		System.out.println(s1==s2);
	}
}
  1. 懒汉式(线程安全, 同步方法)
/**
 * 单例模式4: 懒汉式-同步方法线程安全, 效率低下
 * 
 * @author	Lx 
 * @version 2019年11月26日 上午11:25:01
 * @see com.lx.singleton.Singleton04
 * 
 */
public class Singleton04 {
	// 构造私有化, 防止外部new
	private Singleton04() {};
	// 私有成员静态变量
	private static Singleton04 singleton = null;
	// 公有静态方法
	public static synchronized Singleton04 getInstance(){
		// 此处if判断线程不安全, 多个线程可能同时进if, 创建多次实例
		if(singleton==null) {
			singleton = new Singleton04();
		}	
		return singleton;
	}
	
	public static void main(String[] args) {
		Singleton04 s1 = Singleton04.getInstance();
		Singleton04 s2 = Singleton04.getInstance();
		// true
		System.out.println(s1==s2);
	}
}
  1. 懒汉式(线程安全, 同步代码块)
/**
 * 单例模式5: 懒汉式-同步代码块线程安全, 效率低下
 * 
 * @author Lx
 * @version 2019年11月26日 上午11:25:01
 * @see com.lx.singleton.Singleton05
 * 
 */
public class Singleton05 {
	// 构造私有化, 防止外部new
	private Singleton05() {};
	// 私有成员静态变量
	private static Singleton05 singleton = null;
	// 公有静态方法
	public static Singleton05 getInstance(){
		synchronized(Singleton05.class) {
			if(singleton==null) {
				singleton = new Singleton05();
			}	
		}
		return singleton;
	}
	
	public static void main(String[] args) {
		Singleton05 s1 = Singleton05.getInstance();
		Singleton05 s2 = Singleton05.getInstance();
		// true
		System.out.println(s1==s2);
	}
}
  1. Double-check 双重检查
/**
 * 单例模式1: 懒汉式-双重检查,线程安全高效, 推荐
 * 
 * @author Lx
 * @version 2019年11月26日 上午11:25:01
 * @see com.lx.singleton.Singleton06
 * 
 */
public class Singleton06 {
	// 构造私有化, 防止外部new
	private Singleton06() {};
	// 私有成员静态变量
	private static Singleton06 singleton = null;
	// 公有静态方法
	public static Singleton06 getInstance(){
		// 此处if判断线程不安全, 多个线程可能同时进if, 创建多次实例
		if(singleton==null) {
			synchronized (Singleton06.class) {
				if(singleton==null) {
					singleton = new Singleton06();
				}
			}
		}	
		return singleton;
	}
	
	public static void main(String[] args) {
		Singleton06 s1 = Singleton06.getInstance();
		Singleton06 s2 = Singleton06.getInstance();
		// true
		System.out.println(s1==s2);
	}
}
  1. 静态内部类方式
/**
 * 单例模式7: 懒汉式-静态内部类方式, 懒加载, 安全, 推荐
 * 	1)此方式采用类装载机制来保证初始化实例时只有一个线程
 * 	2)静态内部类方式在Singleton类被加载时并不会立即实例化, 而是在需要实例化时, 调用getInstance方法才会装载GetSingleton07类,从而完成Singleton的实例化
 * 	3)类的静态属性只会在第一次加载类的时候初始化, 所以在这里, JVM帮助我们保证了线程的安全性, 在类进行初始化时, 别的线程是无法进入的
 *  4)优点: 避免了线程不安全, 利用静态内部类特点实现延迟加载, 效率高 
 * 
 * @author Lx
 * @version 2019年11月26日 上午11:25:01
 * @see com.lx.singleton.Singleton07
 * 
 */
public class Singleton07 {
	// 构造私有化, 防止外部new
	private Singleton07() {};
	
	private static class GetSingleton07 {
		private static final Singleton07 SINGLETON  = new Singleton07();
	}
	
	public static synchronized Singleton07 getInstance() {
		return GetSingleton07.SINGLETON;
	}
	public static void main(String[] args) {
		Singleton07 s1 = Singleton07.getInstance();
		Singleton07 s2 = Singleton07.getInstance();
		// true
		System.out.println(s1==s2);
	}
}
  1. 枚举方式
/**
 * 单例模式08: 枚举方式-线程安全, 高效, 推荐
 * 
 * @author Lx
 * @version 2019年11月26日 下午2:49:38
 * @see com.lx.singleton.Singleton08
 * 
 */
public enum Singleton08 {
	INSTANCE;
}

四. JDK中的单例模式

在这里插入图片描述
java.lang包下的Runtime类就是单例中的饿汉式.
里面有几个很有意思的方法:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值