单例模式

单例模式

单例模式即在整个程序里面最多只有一个实例,不可随意创建实例。例如数据库连接池、工程方法等
代码实现要求
1)私有构造器
2)持有该类属性
3)对外提供获取实例的静态方法
饿汉式:线程安全、反射不安全、反序列化不安全

//饿汉式实现,该实现线程安全但是无法防止反射且反序列化时时不安全的
public class Singletonl{
//持有该类属性
  private static Singletonl instance = new Singleton();
  //构造方法私有化
  private Singletonl(){
   
}
//对外提供获取实例的静态方法
public static Singleton getInstance(){
  return this.instance;
}
//由于静态属性在序列化的时候不会被保存,在反序列化的过程中会重新被创建所以需要重写 readResolve方法在反序列化的过程中返回相同属性。
private Object readResolve(){
   return instance;
}

}

登记式:又称静态内部类的形式,是饿汉式的一种改进,与饿汉式相比是可以实现延迟加载。可以看作饿汉式的加强版,线程安全,防止反射攻击,反序列化不安全

public class Singleton2{
//当我们使用getInstance 进行加载创建实例
private static class SingletonHolder{
  private static Singleton2 instance = new Singleton2();
}
private Singleton2(){
//判断内部类属性是否为空,禁用反射,进而控制反射安全
if(SingletonHoder.instance !=null){
throw new lllegalStateException();
}
}

public static Singleton2 getInstance(){
return singletonHolder.instance;
}
//由于静态属性在序列化的时候不会被保存,在反序列化的过程中会重新被创建所以需要重写 readResolve方法在反序列化的过程中返回相同属性。
private Object readResolve(){
return instance;
}
}

枚举式:出现于Java1.5 ,是目前最为推荐的单例模式写法

public enum Singleton3{
//枚举内的属性,相当于全局的,单例的对象,使用过程中只需要获取该属性即可
LNSTANCE{
//实现当前方法
@Override
protected void doSomething(){

}
};
//定义抽象方法
protected absrract void doSomcting();
}

懒汉式:线程不安全,延迟加载,(两种加同步效率低)
双检索: 线程安全,volatile

public class Singleton4{
private static volatile Sinfleton4 instance = null;//添加volatile关键字防止指令重排
private Singleton4(){
}
public Singleton4 getInstance(){
//双检锁机制仅第一次创建进行同步  效率大大提升。但无法100%完全线程安全,因为可能出现指令重排
if(instance==null){
sysnchronized(Singleton4.class){
if(instance==null){
   instance = new Singleton4()}
   }
   }
}
}

instance = new Singleton4()会执行如下操作:
1)分配对象内存空间
2)初始化对象
3)instance指向1)中分配空间
在某些编译器上,可能出现指令重排
1)分配对象内存空间
2)instance指向1)中分配空间
3)初始化对象


Threadkocal:本身不加锁,但是会给每个变量加一个空间副本,即以空间换时间。独立单线程为单例,但是多个线程之间无法保证单例

public calss Singleton5{
private static Singleton5 instance = null;
private Singleton5(){
}
private static final ThreadLocal<Singleton5> threadLocalSingketon = new TgreadLocal<Singleton5>(){
@Override
protected Singleton5 initialValue(){
return new Singleton5();
}
}

public Singleton5 getInstance(){
return threadLocalSingketon.get();
}


}

CAS:利用java原子性进行操作,无锁乐观策略,线程安全

public class Singlcton6{
private static final AtomicReference<Singlcton6> instance = new AtimicReference<>();
private Singleton6(){}
public static final Singleton6 getInstance(){
while(true){
Singleton6 current = instance.get();
if(current != null){
return current
}
current = new Singleton6();
if(instance.compareAndSet(null,current)){
return current
}
}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值