定义
保证一个类只有一个实例,并且提供一个访问这个实例的全局访问点。
使用场景
一般用在一些本质上具有唯一性的系统资源,比如资源管理器这些。
实现技巧
1.首先限制类从构造器实例化,比如new一个实例这种的(一个类只有一个实例的原则)。办法是将构造器变为私有的。
2.既然不能使用构造器,那必须有一个可以获取实例的方法,而且是直接从类获取的,说明是静态的。
3.从这个静态方法里获取每次获取的都是同一个实例。
实现方式
1.饿汉式(还没有使用的时候就已经实例化了)
public class Singleton {
/**
* 单例模式饿汉式,还没有使用实例的时候已经生成好了。
*/
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance(){
return instance;
}
}
优点:访问速度快。在类加载的时候就已经实例化。天生多线程安全。
缺点:一开始就会占用一定的内存。不管你之后会不会使用。有时候类多次加载回生成多个实例。
2.懒汉式(要使用的时候才会实例化)
public class Singleton {
/**
* 单例模式懒汉式,要使用时候才会生成实例。
*/
//私有静态属性
private static Singleton instance;
//私有化构造器
private Singleton() {}
//出于线程安全的考虑加了synchronized
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:只有要使用的时候才会实例化。
缺点:加载延迟,线程不安全。要加synchronized关键字,这样会同步又会更加影响性能。
饿汉式优化(double-check): 只在new实例的时候才会同步,注意要在类属性使用volatile关键字
public class Singleton {
/**
* 单例模式饿汉式,double-check
* 只在new实例的时候才会同步,注意要在类属性使用volatile关键字
*/
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null) {
synchronized (Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}