Java-单例设计模式(Singleton)
单例设计模式是指某个类在整个系统中只能有一个实例对象可被获取和使用的代码模式(如JVM运行环境中的Runtim类)
一、要点:1.唯一实例;
实现方法:构造器私有化
2.创建实例
实现方法:提供一个静态变量保存创建的实例
3.提供实例
实现方法:(1)直接在类下创建实例并用静态变量接收;
(2)用getinstance()方法获取
二、具体实现形式
1.饿汉式:直接创建对象,线程安全,但是无论是否需要都会创建对象,耗费资源
(1)直接实例化
public class SingleTon1 {
public static final SingleTon1 INSTANCE = new SingleTon1();
private SingleTon1(){}
}
(2)枚举:最简洁
public enum SingleTon2 {
INSTANCE
}
(3)静态代码块
public class SingleTon3 {
private SingleTon3(){
}
public static final SingleTon3 INSTANCE ;
static {
INSTANCE = new SingleTon3();
}
}
2.懒汉式:延迟创建对象,懒加载,需要考虑线程安全问题
(1)线程不安全,适用于单线程模式
public class Singleton4 {
private Singleton4(){
}
private static Singleton4 instance;
//线程不安全
public static Singleton4 getInstance(){
if (null == instance) {
instance = new Singleton4();
}
return instance;
}
}
(2)线程安全,可用于多线程,使用双重检查锁(双检锁)进行锁优化
public class Singleton5 {
private Singleton5(){
}
private static Singleton5 instance;
public static Singleton5 getInstance() {
//双重检查锁
if (null == instance) {
synchronized (Singleton5.class){
if (instance == null) {
instance = new Singleton5();
}
}
}
return instance;
}
}
(3)静态内部类:
内部类会在使用时再初始化,所以会延迟创建对象
并且JVM初始化的clinit(class+initialize)方法会保证clinit再多线程中被正确的加锁、同步,从而保证了线程安全
public class Singleton6 {
private Singleton6(){}
public static class Inner{
private static final Singleton6 instance = new Singleton6();
}
public static Singleton6 getInstance(){
return Inner.instance;
}
三、如何选择
对于构建简单,加载后立即使用的单例对象,建议饿汉式
对于构建复杂,耗时长且不是所有此类都会用到的单例对象,建议懒汉式