设计模式之单例模式

单例模式:一个类只有一个实例对象,提供一个全局的访问点

作用:保证一个类只有一个对象,降低对象之间的耦合度

单例的一般实现方法:

public class Singleton {
		//    1、创建私有变量instance,用来记录Singleton的唯一实例
		//    2、内部进行实例化
			private static Singleton instance = new Singleton();
		//    3、把类的构造方法私有化,不让外部调用构造方法
			private Singleton() {

			}
		//    4、定义公共的方法提供该类的全局唯一访问点
		//    5、外部通过调用getInstance()来返回唯一的实例
			public static Singleton getInstance() {
				return instance;
			}
		}
单例的实现方式可以分为2大类6种:

饿汉式、枚举类型、懒汉式之基础实现、懒汉式之同步锁、懒汉式之双重检验锁、静态内部类

1、饿汉式

原理:依赖JVM类加载机制,保证单例只会被创建一次,即线程安全。

/**
			 * 饿汉式
			 * 应用场景:
			 *  要求初始化速度快,占用内存少
			 */
			class Singleton2 {
			//    1、加载该类时,单例就会自动被创建
				private static Singleton2 myInstance = new Singleton2();
			//    2、构造函数设置为私有

				public Singleton2() {
				}

			//    3、通过静态方法获得创建的单例
				public static Singleton2 getMyInstance() {
					return myInstance;
				}
			}
2、枚举类型

原理:根据枚举的特点,满足单例模式所需的创建单例、线程安全、实现简洁的需求

/**
			 * 枚举实现
			 * 这是最简单、易用的单例实现方法
			 */
			enum Singleton3 {
				//    定义一个 枚举,即为单例的一个实例
				INSTANCE;
			//    隐藏一个空的构造方法
				private Singleton3() {}
			}

				//获取单例的方式
			    Singleton3 singleton3 = Singleton3.INSTANCE;
3、懒汉式之基础实现
原理:和饿汉式最大的区别就是实例创建的时机
饿汉式:创建时机不可控,在类加载的时候自动创建

懒汉式:在有需求的时候手动创建

/**
			 * 懒汉式(基础实现)
			 */
			class Singleton4 {
			//    1、类加载时,先不自动创建单例
				private static Singleton4 myInstance = null;
			//    2、构造函数
				private Singleton4() {}
			//    3、需要时才手动调用newInstance()创建
				public static Singleton4 newInstance() {
			//        先判断单例是否为空,避免重复创建
					if (myInstance == null) {
						myInstance = new Singleton4();
					}
					return myInstance;
				}
			}

缺点:线程不安全

4、懒汉式之同步锁
原理:使用同步锁synchronized锁住创建单例的方法,防止多个线程同时调用,从而避免造成单例的多次被创建

/**
			 * 懒汉式之同步锁
			 *  线程安全
			 *  缺点:每次访问都需要进行线程同步(调用synchronized),造成过多的同步开销
			 */
			class Singleton5 {
				private static Singleton5 myInstance = null;

				private Singleton5() {}

				public static Singleton5 newInstance() {
					
						synchronized (Singleton5.class) {
							if (myInstance == null) {
								myInstance = new Singleton5();
							}
						}
					
					return myInstance;
				}
			}
5、懒汉式之双重检验锁
原理:在同步锁的基础上,添加一层if判断,若单例已创建,就不需要在执行加锁操作就可以获取实例,从而提高性能


/**
			 * 懒汉式之双重校验
			 注意:多重判断,容易出错
			 */
			class Singleton6 {
				private static Singleton6 myInstance = null;

				public Singleton6() {
				}

				public static Singleton6 newInstance() {
					if ( myInstance == null) {
						synchronized(Singleton6.class) {
							if (myInstance == null) {
								myInstance = new Singleton6();
							}
						}
					}
					return myInstance;
				}
			}
6、静态内部类
原理:根据静态内部类的特性,解决按需加载、线程安全,同时实现简洁
/**
			 * 静态内部类
			 * 调用过程:
			 *  1、外部调用类的newInstance()
			 *  2、自动调用SIngleton7.newInstance()
			 *      此时单例类Singleton8得到初始化
			 *      而该类在装载 & 被初始化时,会初始化它的静态域,从而创建单例;
			 *      由于是静态域,因此只会JVM只会加载1遍,Java虚拟机保证了线程安全性
			 *  3、最终只创建一个单例
			 */
			class Singleton7 {
			//    1、创建静态内部类
				private static class Singleton8 {
			//        在静态内部类里创建单例
					private static Singleton7 myInstance = new Singleton7();
				}

				private Singleton7() {}

				public static Singleton7 newInstance() {
					return Singleton8.myInstance;
				}
			}


单例模式需要注意些什么?

    构造函数要私有化    

    含有一个该类的静态私有对象

    有一个静态的公有的函数用于创建或获取他本身的静态私有对象

    需要考虑到线程同步问题



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值