【设计模式】设计模式之单例模式

单例模式

  • 简介
    • 特点
    • 优点
    • 缺点
    • 使用场景
    • 注意
  • 1.饿汉式(静态常量)
    • 优点
    • 缺点
    • 代码示例
  • 2.饿汉式(静态代码块)
  • 3.懒汉式(线程不安全)
    • 优点
    • 缺点
    • 代码示例
  • 4.懒汉式(线程安全,同步方法)
    • 优点
    • 缺点
    • 代码示例
  • 5.懒汉式(同步代码块)
    • 代码示例
  • 6.双重检查
    • 优点
    • 代码示例
  • 7.静态内部类
    • 优点
    • 代码示例
  • 8.枚举
    • 优点
    • 代码示例

简介

特点

  • 只有一个实例
  • 自我实例化
  • 提供全局访问点

优点

  • 节省系统资源、提高系统效率
  • 控制客户对它的访问

缺点

  • 单例类的职责过重,违背了单一职责原则
  • 没有抽象类,扩展困难

使用场景

  • 需要频繁创建和销毁的对象
  • 创建对象时耗时过多或耗费资源过多但又经常使用的对象
  • 频繁访问数据库或者文件的对象(数据源,工厂等)

注意

需要实例化对象的时候,使用相应的获取对象的方法,而不是通过new得到

1.饿汉式(静态常量)

类装载时实例化对象

优点

  • 写法简单
  • 在类装载的时候完成实例化,避免了线程同步问题

缺点

在类加载的时候完成实例化,没有实现懒加载的效果
如果该实例没有被使用,则会造成内存浪费

代码示例

public class Singleton{
	//构造器私有化
	private Singleton(){}
	//内部创建实例对象
	private final static Singleton instance = new Singleton();
	//共有静态方法,返回实例对象
	public static Singleton getSingleton(){
		return instance;
	}
}

2.饿汉式(静态代码块)

同上,代码写法有点区别

public class Singleton{
	//构造器私有化
	private Singleton(){}
	//内部声明静态常量
	private static Singleton singleton;
	static{
		//静态代码块中创建单例对象
		singleton = new Singleton();
	}
	//共有静态方法,返回实例对象
	public static Singleton getSingleton(){
		return singleton;
	}
}

3.懒汉式(线程不安全)

优点

起到了懒加载的效果

缺点

线程不安全

代码示例

public class Singleton{
	//内部声明静态常量
	private static Singleton singleton;
	//构造器私有化
	private Singleton(){}
	//共有静态方法,使用该方法时创建实例对象
	public static Singleton getSingleton(){
		if(singleton == null){
			singleton= new Singleton();
		}
		return singleton;
	}
}

4.懒汉式(线程安全,同步方法)

优点

解决了线程不安全问题

缺点

效率低

代码示例

public class Singleton{
	//内部声明静态常量
	private static Singleton singleton;
	//构造器私有化
	private Singleton(){}
	//共有静态方法,使用该方法时创建实例对象,加锁实现线程安全
	public static synchronized Singleton getSingleton(){
		if(singleton == null){
			singleton= new Singleton();
		}
		return singleton;
	}
}

5.懒汉式(同步代码块)

不能实现线程安全

代码示例

public class Singleton{
	//内部声明静态常量
	private static Singleton singleton;
	//构造器私有化
	private Singleton(){}
	//共有静态方法,使用该方法时创建实例对象,加锁实现线程安全
	public static Singleton getSingleton(){
		if(singleton == null){
			//不靠谱的写法,无法保证线程安全
			synchronized(Singlenton.class){
			singleton= new Singleton();
			}
		}
		return singleton;
	}
}

6.双重检查

优点

  • 提高了效率
  • 解决了线程安全问题

代码示例

public class Singleton{
	//内部声明静态常量
	private static volatile Singleton singleton;
	//构造器私有化
	private Singleton(){}
	//共有静态方法,使用该方法时创建实例对象
	public static Singleton getSingleton(){
		if(singleton == null){
			//不靠谱的写法,无法保证线程安全
			synchronized(Singlenton.class){
				if(singleton == null){
					singleton= new Singleton();
				}
			}
		}
		return singleton;
	}
}

7.静态内部类

  • 静态内部类不会随着类加载而加载
  • 内部类加载时线程安全

优点

  • 采用类装载机质保证初始化实例时只有一个线程,实现了线程安全
  • 类的静态属性只会在第一次类加载的时候初始化,实现了单例
  • 内部类不会随着外部类的加载而加载,实现类懒加载

代码示例

public class Singleton{
	//内部声明静态常量
	private static volatile Singleton singleton;
	//构造器私有化
	private Singleton(){}
	//共有静态方法,使用该方法时创建实例对象
	public static Singleton getSingleton(){
		return InnerSingleton.INSTANCE;
	}
	//静态内部类
	private static class InnerSingleton{
		private static final Singleton INSTANCE =  new Singleton();
	}
}

8.枚举

优点

  • 线程安全
  • 防止反序列化重新创建新对象

代码示例

enum Singleton{
	INSTANCE;
	//枚举类需要有方法的存在,这里这个方法就是凑数的
	public void mothed(){
		
	}
}

你可能感兴趣的:(【设计模式】设计模式之单例模式)