单例设计模式

单例设计模式是最常用的设计模式之一,它提供了一种在多线程情况下保证实例唯一性的解决方案,单例模式虽然简单,但实现方式却有很多。
采用单例模式,针对频繁使用的对象,可以省去new操作花费的时间,这对于哪些重量级对象而言,是可以省掉一笔非常可观的系统开销。
对于new操作的次数减少,系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。
因此,对于系统的关键组件和被频繁使用的对象,使用单例模式可以有效的改善系统的性能。

1 饿汉式

饿汉式指的是当类被加载的时候就实例化,并创建单例对象。如果类中的成员变量不多,且占用内存不大,这种方式也可以。如果类中的成员需要占用比较重的资源,就有点不妥。单例模式对象不能被继承,所以整个类用final修饰固化。

package designpaten;
public final class Singleton_Hungry {
      private static Singleton_Hungry instance  = new Singleton_Hungry();
     //构造函数私有化,不允许其他类直接通过new的方式创建新对象
      private Singleton_Hungry() {
    	  
      }
      public Singleton_Hungry getInstance() {
    	  return instance;
      }
}

2 懒汉式

所谓的懒汉式指的就是只有在使用的时候才开始构造对象,这样可以避免在类加载的时候就提前创建。但这里要加锁,不然在多线程环境下可能会创建多个对象。

package designpaten;
public final class Singleton_Lazy {
      private static Singleton_Lazy instance  = null;
     //构造函数私有化,不允许其他类直接通过new的方式创建新对象
      private Singleton_Lazy() { 
      }
      public static synchronized Singleton_Lazy getInstance() {
    	  if(instance == null) {
    		  instance = new Singleton_Lazy();
    	  }
    	  return instance;
      }
}

3 Double-check

Dobule-check采用的也是一种同步机制,只不过是在首次初始化时加锁,之后就允许多个线程同时进行getInstance方法的调用来获得类的实例。

package designpaten;
public final class Singleton_DoubleCheck {
      private static Singleton_DoubleCheck instance  = null;
     //构造函数私有化,不允许其他类直接通过new的方式创建新对象
      private Singleton_DoubleCheck() { 
      }
      public static  Singleton_DoubleCheck getInstance() {
    	  if(instance == null) {
    		  synchronized(Singleton_DoubleCheck.class) {
    			  if(instance == null) {
            		  instance = new Singleton_DoubleCheck();
    			  }
    		  }
    	  }
    	  return instance;
      }
}

4 Holder方法即内部类方式

Holder方式完全是借助了类加载的特点。将instance成员放到了静态内部类Holder之中,因此单例类的初始化过程并不会创建单例实例。只有Holder被主动引用的时候才会创建单例实例。

package designpaten;
public final class Singleton_InnerClass {
      private static Singleton_InnerClass instance  = null;
     //构造函数私有化,不允许其他类直接通过new的方式创建新对象
      private Singleton_InnerClass() { 
      }
      private static class Holder{
    	  private static Singleton_InnerClass instance = new Singleton_InnerClass();
      }
      public static Singleton_InnerClass getInstance() {
    	  return Holder.instance;
      }
}

5 枚举方式

枚举类型不允许被继承,同样是线程安全的且只能被实例化一次,但是枚举类型不能够懒加载。也是高效JAVA编程作者推荐的方法。在这种实现方式中,既可以避免多线程同步问题;还可以防止通过反射和反序列化来重新创建新的对象。 因为Java虚拟机会保证枚举对象的唯一性,因此每一个枚举类型和定义的枚举变量在JVM中都是唯一的。

package designpaten;
//枚举类本身就是final的,不允许被继承
public enum Singleton_Enum {
      INSTANCE;
      Singleton_Enum() {}
      public static Singleton_Enum getInstance() {
    	  return INSTANCE;
      }
}

通过枚举定义单例,还有一种实现方式,就是将枚举类作为内部类来用。

public class SingleDemo {
   private SingleDemo(){ 
   }
   public static enum Demo{
	   INSTANCE;
	   private  SingleDemo instance = null;
	   private Demo() {
		   instance= new SingleDemo();
	   }
	   public   SingleDemo create() {
		   System.out.println("hello");
		   return instance;
	   }
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunny_daily

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值