【黑马程序员】Java中单例设计模式的几种常见写法
前几天在上Java基础课的时候,讲到private关键字的作用,就是所有被private修饰的成员变量和常量都只能在本类中使用。也就说构造方法一旦被private修饰就只能在本类中使用。不能再外部创建本类的实例。一般的应用场景有两个,一个是工具类,我们就是不希望别人创建对象,所以把构造方法私有化。另一个就是单例设计模式中,我们也不希望别人随意创建实例,要想得到本类的实例,必须调用给提供的static的获取实例的方法才可以。今天咱们就来总结一下,单例设计模式的几种常见的写法有什么优缺点。 第一种,懒汉式,线程不安全
01 public class Singleton {
02 private static Singleton instance; 03 private Singleton (){} 04
05 public static Singleton getInstance() { 06 if (instance == null) {
07 instance = new Singleton(); 08 }
09 return instance; 10 } 11 }
第二种,懒汉式,线程安全
01 public class Singleton {
02 private static Singleton instance; 03 private Singleton (){}
04 public static synchronized Singleton getInstance() { 05 if (instance == null) {
06 instance = new Singleton(); 07 }
08 return instance; 09 } 10 }
黑马程序员济南中心 编著
这种写法,虽然多线程的时候不会出问题,但是效率太低。 第三种,饿汉式
1 public class Singleton {
2 private static Singleton instance = new Singleton(); 3 private Singleton (){}
4 public static Singleton getInstance() { 5 return instance; 6 } 7 }
在类加载时创建,避免多线程的问题。 第四种,静态内部类
1 public class Singleton {
2 private static class SingletonHolder {
3 private static final Singleton INSTANCE = new Singleton(); 4 }
5 private Singleton (){}
6 public static final Singleton getInstance() { 7 return SingletonHolder.INSTANCE; 8 } 9 }
也是用类加载机制来保证初始化时只用一个线程,但是好处是SingleTon被加载了,实例不一定被穿件,只用调用getInstance()方法时,才会显示的加载SingletonHolder,从而实例化Singleton. 第五种方式,枚举
1 public enum Singleton { 2 INSTANCE;
3 public void method() { 4 } 5 }
黑马程序员济南中心 编著
第六种,双重检校 01 public class Singleton {
02 private volatile static Singleton singleton; 03 private Singleton (){}
04 public static Singleton getSingleton() { 05 if (singleton == null) {
06 synchronized (Singleton.class) { 07 if (singleton == null) {
08 singleton = new Singleton(); 09 } 10 } 11 }
12 return singleton; 13 } 14 }
黑马程序员济南中心 编著