1.概念
确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
。
即其构造方法必须是private,只有一个实例,该实例属于当前类的类成员属性,静态变量。(类变量就是静态变量,static修饰)。
还需提供一个静态方法,向外界提供当前类的实例,实例只能在类的内部实例化。
2.作用
确保一个类只有一个实例的存在。
例:序号生成器、web页面的计数器。
或者创建一个对象需要消耗很多资源,例如访问io或者数据库资源
根据实例化方法不同分为饿汉式和懒汉式
3.饿汉式
即在类加载的时候进行实例化。
public class SingletonPattern {
public static void main(String[] args) {
}
}
//饿汉式
class Singleton{
private static final Singleton singleton = new Singleton();
private Singleton(){ }
public static Singleton getInstance(){
return singleton;
}
}
饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。
4.懒汉式
类加载过程中不进行实例化,第一次使用的时候进行实例化。
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//静态工厂方法
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例。
1.加synchronized 锁
//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton {
private Singleton() {}
private static Singleton single=null;
//静态工厂方法
public synchronized static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
2、双重检查锁定
两个检查是否为空,一个锁
private volatile static Singleton singleton;
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
说明:singleton = new Singleton(); 创建对象不是原子性操作,有可能会出问题。
分为三步
- 分配内存空间
- 执行构造方法,初始化对象
- 把这个对象指向这个空间
3、静态内部类
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}