单列设计模式几种写法的比较

本文介绍了单例模式的两种实现方式:饿汉式和懒汉式。饿汉式在类加载时创建实例,适用于频繁使用的场景;懒汉式则在首次访问时创建实例,适合较少使用的场景。文章详细讨论了懒汉式的线程安全问题及解决方案。

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

单例模式有两种写法,懒汉式和饿汉式
1.饿汉式:在程序启动或单列模式类被加载的时候,单例模式实例就已经被创建。
2.懒汉式:当程序第一次访问单例模式实例时才进行创建。懒汉式实现了延迟加载的功能。
选择:当单例模式在系统中经常被用到时,饿汉式是一个不错的选择。但如果单例模式在系统中很少使用或者几乎不会用到,那么可以选择懒汉式。
好了,写代码吧。

饿汉式代码

public Simple(){
	//生成静态实例对象
     private static Single s=new Single();
	//私有化空构造方法,使其不能在外面new        
     private Single(){}  
	//生成公有的供外界访问的方法
     public static Simple getSimple(){
         return s;
     } 
}

上面的饿汉式在类一加载的时候,实例对象就已生成,造成资源的浪费。饿汉式优化代码实现延缓加载

public class Single{
		
	 //使用内部类,在调用时才加载,实现了延缓加载
	private static class SingleHolder {
	//生成静态实例对象
		private static Single s=new Single();
	}
		
	//私有化空构造方法,使其不能在外面new        
	 private Single(){}
	//生成公有的供外界访问的方法
	 public static Single getSimple(){
	       return SingleHolder.s;
	 } 
}


懒汉式代码

class Single{
   private static Single s = null;
   private Single(){}
   public static Single getInstance() {
       if (s == null){
         s = new Single();
	}
       return s;
  }
}
但是这种方法对于多线程来说不安全,要对生成对象的部分进行加锁,加锁分为两种,一种是在方法上加锁,一种是在代码块上加锁。
先用第一种在方法上加锁

class Single{
   private static Single s = null;
   private Single(){}
   public static synchronized Single getInstance() {
       if (s == null){
         s = new Single();
	}
       return s;
  }
}
这一种可以解决线程不安全的问题,但是不是最好的,因为在第一次生成对象之后,以后每次访问都需要进行锁的判断,效率上会有影响。
在用第二种在代码块上加锁

class Single{
   private static Single s = null;
   private Single(){}
   public static Single getInstance() {
       if (s == null){
	  synchronized(Single.class) {
	      if(s == null) {
               s = new Single();
	      }
	  }
	}
       return s;
  }
}
在代码块里加了锁,还双重判断,这个是有必要的。因为加入有两个线程同时运行到第一个if判断的地方,判断都为空,一个线程先进去生成一个实例,第二个线程也进去,如果没有第二个if判断,就会也new出一个实例,所以用两个if判断是有必要的。还有一点是这个锁的对象时该类的字节码对象,因为这个方法是静态方法,被放在静态方法区里面了,用类的字节码,能保证对不同线程是同一个对象。懒汉模式里最后一种写法比较好。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值