java 单例的几种设计

设计步骤:

1:构造器私有化
2: 含有一个该类的静态变量来保存这个唯一的实例
3:对外提供获取该实例对象的方式

一:饿汉式的几种设计

1:直接创建 这种必须用public来修饰变量 不然外部访问不到

public class Singleton {
	public static final Singleton1 INSTANCE = new Singleton();
	private Singleton(){
		
	}
}

调用:

Singleton s = Singleton.INSTANCE;

2:枚举

public enum Singleton {
	INSTANCE
}

调用:

Singleton s = Singleton.INSTANCE;

3:静态代码块 这种必须用public来修饰变量 不然外部访问不到

public class Singleton {
	public static final Singleton3 INSTANCE;
	private String info;
	static{
		try {
			Properties pro = new Properties();
	  pro.load(Singleton3.class.getClassLoader().getResourceAsStream("single.properties"));
			INSTANCE = new Singleton3(pro.getProperty("info"));
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	private Singleton(String info){
		this.info = info;
	}



	

这是用在特殊场合比如根据某些配置的参数初始化

调用方法

Singleton s = Singleton.INSTANCE;

 二:懒汉式的几种设计 privat来修饰变量

1:内部内

/*
 * 在内部类被加载和初始化时,才创建INSTANCE实例对象
 * 静态内部类不会自动随着外部类的加载和初始化而初始化,它是要单独去加载和初始化的。
 * 因为是在内部类加载和初始化时,创建的,因此是线程安全的
 */
public class Singleton {
	private Singleton6(){
		
	}
	private static class Inner{
		private static final Singleton INSTANCE = new Singleton();
	}
	
	public static Singleton getInstance(){
		return Inner.INSTANCE;
	}
}

2:同步锁 线程安全

public class A {

    private static A INSTANCE;

    private A(){

    }
    public static synchronized A getInstance() {
        if(INSTANCE==null){
            INSTANCE=new A();
        }
       return INSTANCE;
   }

}

3:DDL模式(双端检索模式)

public class A {

    private static A INSTANCE;

    private A(){

    }
    public static  A getInstance() {
        if(INSTANCE==null){
            synchronized (A.class){
                if(INSTANCE==null){
                    INSTANCE=new A();
                }
            }
        }
       return INSTANCE;
   }

}

ddl模式可能存在指令重排所以有极低概率发生错误 jmm和jvm知识

指令重排问题略解:INSTANCE=new A(); 分三步完成:

 1:memory=allocate(); 内存分配

2:instance(memory);初始化对象

3:instance=memory:指向分配的地址 instance!=null;

指令重排可以打乱执行顺序。

代码优化为:懒汉式最终版

public class A {

    private static volatile A INSTANCE;

    private A(){

    }
    public static  A getInstance() {
        if(INSTANCE==null){
            synchronized (A.class){
                if(INSTANCE==null){
                    INSTANCE=new A();
                }
            }
        }
       return INSTANCE;
   }

}

volatile 关键字可以禁止指令重排 其作用是见性和禁止指令重排但不能保障原子性 下一篇笔记专门记录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值