单例模式之饿汉模式、懒汉模式和枚举类型

单例设计模式,是23中程序设计思想之一应用例子:回收站,任务管理器。单例模式可以分为懒汉模式即非延迟加载,饱汉模式即延迟加载(在需要的时候再加载)。下面一一介绍。针对是否考虑资源浪费、线程安全有不同的实现方式。
饱汉模式一--缺点:多线程不安全,有点:节约资源
/*、
*/
public class Singleton1 {

	private static Singleton1 singleton1 = null;
	private Singleton1() {
		
	}
	
	public static synchronized Singleton1 getSingleton1() {
		if(singleton1 != null) {
			singleton1 = new Singleton1();
		}
		return singleton1;
	}
	
	public static void main(String[] args) {
		System.out.println(Singleton1.getSingleton1() == Singleton1.getSingleton1());
	}
}

输出:true

饱汉模式二:加同步锁,但是完全变成了串行,效率太低,甚至不如懒汉模式。
public class Singleton1 {

	private static Singleton1 singleton1 = null;
	private Singleton1() {
		
	}
	
	public static synchronized Singleton1 getSingleton1() {
		if(singleton1 != null) {
			singleton1 = new Singleton1();
		}
		return singleton1;
	}
	
	public static void main(String[] args) {
		System.out.println(Singleton1.getSingleton1() == Singleton1.getSingleton1());
	}
}

输出:true
饱汉模式三:使用双重检查锁(Double Check Lock,简称DCL)机制,貌似已经实现了线程安全+延迟加载,但是由于指令重载,有可能得到半个对象。
public class Singleton2 {

	private static Singleton2 singleton2 = null;
	
	public int f1 = 1;		//防止部分初始化问题
	public int f2 = 2;
	private Singleton2() {
		
	}
	
	public static Singleton2 getSingleton2() {
		if(singleton2 != null) {
			synchronized (Singleton2.class) {
				if(singleton2 != null) {
					return singleton2 = new Singleton2();
				}
			}
		}
		return singleton2;
	}
	
	public static void main(String[] args) {
		System.out.println(Singleton2.getSingleton2() == Singleton2.getSingleton2());
	}
}

输出:true
饱汉模式四:使用volatile关键字,保证原子性。
public class Singleton3 {

	private static volatile Singleton3 singleton3 = null;
	
	public int f1 = 1;		//防止部分初始化问题
	public int f2 = 2;
	private Singleton3() {
		
	}
	
	public static Singleton3 getSingleton3() {
		if(singleton3 != null) {
			synchronized (Singleton3.class) {
				if(singleton3 != null) {
					return singleton3 = new Singleton3();
				}
			}
		}
		return singleton3;
	}
	
	public static void main(String[] args) {
		System.out.println(Singleton3.getSingleton3() == Singleton3.getSingleton3());
	}
}

输出:true
饿汉模式
饿汉模式一:由于很饥饿,所以在一开始就得到唯一的实例化对象。得益于类的加载机制,恶汉模式完全是线程安全的。
public class Singleton2 {
  private static final Singleton4 singleton4 = new Singleton4();
  private Singleton4() {
  }
  public static Singleton4 getSingleton4 () {
    return singleton4;
  }
public static void main(String[] args) {
		System.out.println(Singleton4.getSingleton4() == Singleton4.getSingleton4());
}

输出:true
饿汉模式二:最推荐使用的方式
public class Singleton3 {

	private static class Inner{
		
		private static final Singleton3 singleton = new Singleton3();
	}
	private Singleton3() {
		
	}
	
	public static Singleton3 getSingleton() {
		return Inner.singleton;
	}
	
	public static void main(String[] args) {
		System.out.println(Singleton3.getSingleton() == Singleton3.getSingleton());
	}
}

输出:true

介绍到这里就算完了,但是如果考虑到反射和序列化,使用private修饰,仍旧会破坏单例模式,所以可以使用Java“最丑陋的语法糖”枚举类型,没有研究那么深,所以就只粘贴代码了。

public enum Singleton4_1 {
  SINGLETON("enum is the easiest singleton pattern, but not the most readable") {
    public void testAbsMethod() {
      print();
      System.out.println("enum is ugly, but so flexible to make lots of trick");
    }
  };
  private String comment = null;
  Singleton4_1(String comment) {
    this.comment = comment;
  }
  public void print() {
    System.out.println("comment=" + comment);
  }
  abstract public void testAbsMethod();
  public static Singleton4_1 getInstance() {
    return SINGLETON;
  }
public static void main(String[] args) {
		
		System.out.println(Singleton4_1.getInstance() == Singleton4_1.getInstance());
	}
}

测试之后输出true
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值