单例模式
概念
单例模式属于创建型模式,提供了一种创建对象的最佳方式,
特点:
- 单例模式只能有一个实例
- 单例模式的构造器必须私有化,同时自己为自己创建一个唯一实例
- 需要对外提供访问该实例的接口
目的:
主要解决一个全局使用的类频繁地创建与销毁,保证一个类只有一个实例,并且提供了访问该实例的全局访问接口。
优点:
在内存里只存在一个实例,减少了内存的开销,同时也避免对资源的多重占有。
单例模式的实现
1、饿汉式:
优点:
- 实现简单
- 多线程安全
- 没有进行加锁处理,执行效率较高
public class Singleton {
// 饿汉式
//一上来直接创建对象
private static Singleton instance = new Singleton();
//私有化构造器
private Singleton(){}
//提供对外的访问接口
public static Singleton getInstance(){
return instance;
}
}
2、懒汉式(线程不安全)
- 线程不安全
- 实现简单
- 支持lazy加载
- 不能在多线程模式下工作,因为线程不安全
public class Singleton {
//懒汉式,线程不安全
//创建对象
private static Singleton instance = null;
//私有化构造器
private Singleton(){}
//提供对外的访问接口
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
3、懒汉式,线程安全
- 多线程安全
- 支持lazy加载
- 实现简单
- 但是效率低下
public class Singleton {
//懒汉式,线程安全
//创建对象
private static Singleton instance = null;
//私有化构造器
private Singleton(){}
//提供对外的访问接口
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
4、双检锁(双重校验锁)
- 多线程先安全
- 支持lazy加载
- 实现较为复杂
- 能够保证在多线程情况下安全的同时又能保证高性能
public class Singleton {
//双重校验锁/双检锁
private static volatile Singleton instance = null;
//私有化构造器
private Singleton(){}
//对外访问接口
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
5、静态内部类(登记式)
- 多线程安全
- 和饿汉式先比支持lazy加载
- 能够达到和双重校验锁方式达到一样的效果,但实现简单
public class Singleton {
//静态内部类(登记式)
private static class SingletonHandler{
private static final Singleton INSTANCE = new Singleton();
}
//私有化构造器
private Singleton(){}
//提供对外的访问接口
public static Singleton getInstance(){
return SingletonHandler.INSTANCE;
}
}
6、枚举方式
- 支持多线程
- 支持lazy加载,实现简单
//枚举法
public enum Singleton{
INSTANCE;
}