线程安全的单例模式

本文详细介绍了单例模式的四种实现方式:普通单例、synchronized关键字实现、双重检测单例模式及内部类单例。探讨了每种方式的优缺点,并深入分析了指令重排序对双重检测单例模式的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、普通单例

多线程环境下还是会创建多个对象。

2、使用sycnhronized关键字实现单例

使用sycnhronzied修饰创建对象的方法。只有一个线程能进方法去创建对象保证单例,这种方法没有下面方法的效率高。

 3、双重检测单例模式

优点:在多线程的情况下最高性能的使用了锁机制保证了线程安全

缺点:创建对象有三个步骤,A1、分配对象的内存空间,A2、初始化对象,A3、设置引用指向内存空间。

如果出现A2与A3之间的指令从排序,A3设置引用指向内存空间后在进行A2操作。在执行A2之前其他线程获取到的引用相当于空引用,此时对象还没有初始化。

下面是伪代码:
memory=allocate();       //A1:分配对象的内存空间
ctorlnstance(memory);    //A2初始化对象
instance =memory;             //A3:设置instance指向刚分配的内存地址

 

弥补:设置成员变量Singleton 使用volatile关键字修饰,方式第3步和第二部指令从排序。

public  class Singleton{
	
	public Singleton(){}//属性私有化,保证只能在其他地方不能创建对象

	public static volatile Singleton singleton; //使用volatile修饰防止指令重排序
	
	public static  Singleton  getSingleton(){
	
	    if(singleton==null){
	
		    synchronized(Singleton.class){
		
			    if(singleton==null){
				    singleton=new Singleton();
			    }
		    }
	    }
	
	    return singleton;
	
	}
	
}

4、内部类单例

优点:使用java虚拟机类加载机制进行单例的创建对象,在类加载的时候进行初始化。

因为在多线程环境下,jvm对一个类的初始化会做限制,同一时间只会允许一个线程去初始化一个类。

 

public class Singleton{

    private Singleton(){};//构造方法私有化,禁止在其他地方创建对象
		        
	static{
	    System.out.println("This'sstaticcodeblock!");
    }
		        
    //静态内部类进行对象创建
	private static class SingletonHandler{
		        
		  private static final Singleton INSTANCE = new Singleton();
		                
		  static{
		       System.out.println("This'sinnerClass'sstaticcodeblock");
		  }
	}
		        
		        
	public static Singleton getInstance(){

		   return SingletonHandler.INSTANCE;

	}
		                
		
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值