单例模式:确保一个类只有一个实例,并提供一个全局访问点
1.第一个实现方式
package com.TWO;
//这个种方法将延迟实例化,如果我们不需要这个实例,它就永远不会产生
public class Singleton {
private static Singleton uniqueInstance;
//构造器是私有的,只有Singleton类内部才可以调用
private Singleton(){}
public static Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
这种方式实现的单例在多线程的情况 不可以保证单例
2.加锁单例
package com.TWO;
//这个种方法将延迟实例化,如果我们不需要这个实例,它就永远不会产生
public class Singleton {
private static Singleton uniqueInstance;
//构造器是私有的,只有Singleton类内部才可以调用
private Singleton(){}
public static synchronized Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
这种方式的单例模式 简单有效 ,但是效率很差
3.利用JVM在加载类的时候就创建对象单例的方式
package com.TWO;
//这个种方法将延迟实例化,如果我们不需要这个实例,它就永远不会产生
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
//构造器是私有的,只有Singleton类内部才可以调用
private Singleton(){}
public static synchronized Singleton getInstance(){
return uniqueInstance;
}
}
这种方式可以确保在多线程情况下也是有效的,但是不管你使用不使用这个单例,它一直在内存在存在
4.用”双重检查加锁”,在getinstance()中减少使用同步
package com.TWO;
//这个种方法将延迟实例化,如果我们不需要这个实例,它就永远不会产生
public class Singleton {
//volatile确保:当uniqueInstance变量被初始化成Singleton实例时,多个线程正确得处理uniqueInstance变量
private volatile static Singleton uniqueInstance;
//构造器是私有的,只有Singleton类内部才可以调用
private Singleton(){}
public static Singleton getInstance(){
//检查实例 如果不存在,就进入同步区域
if(uniqueInstance == null){
synchronized (Singleton.class) {
if(uniqueInstance == null ){
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}