java使用枚举、饿汉式、懒汉式、内部类实现单例设计模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ljh_learn_from_base/article/details/72802777
/*
    修改于2018-09-10 23:12
    实现单例的四种方式:
    饿汉式(线程安全,调用效率高,但是不能延时加载)
    懒汉式(线程安全,调用效率不高,可以延时加载)
    静态内部类式(线程安全,调用效率高,但是可以延时加载)
    枚举单例(线程安全,调用效率高,不能延时加载)
*/
/*单例设计模式:保证一个类在使用过程中,只有一个实例。优势就是他的作用,这个类永远只有一个实例。
        步骤:  1.将该类的构造方法私有;

                2. 在内部实例化一个该类的实例;

                3. 提供接口给外部访问。

        //饿汉式://线程安全,“饿汉式”是在不管你用的用不上,一开始就建立这个单例对象:*/  
/* 这种写法不会出现并发问题,但是它是饿汉式的,在ClassLoader加载类后SingletonDemo 的实例就会第一时间被创建,
饿汉式的创建方式在一些场景中将无法使用:譬如SingletonDemo 实例的创建是依赖参数或者配置 文件的,
  在getInstance()之前必须调用某个方法设置参数给它,那样这种单例写法就无法使用了。 */  
    
   
    public class SingletonDemo {
                private SingletonDemo (){}  // 1.
                private static final SingletonDemo single = new SingletonDemo();  // 2.
                public static SingletonDemo getInstance(){  // 3.
                        return single;
                }
        }

public  class Singleton2 {     
    /* 使用内部类来实现单例模式,线程安全
     这种写法仍然使用JVM本身机制保证了线程安全问题;由于SingletonHolder是私有的,
     除了getInstance()之外没有办法访问它,因此它是懒汉式的;
     同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖JDK版本。*/
    private Singleton2(){}
    private static class SingletonHolder {     
       //单例对象
        static final Singleton2 INSTANCE = new Singleton2();     
    }     
      
    public static Singleton2 getInstance() {     
        return SingletonHolder.INSTANCE;     
    }     
}   



        //懒汉式:“懒汉式”是在你真正用到的时候才去建这个单例对象:延迟加载
使用DCL(Double checked Locking) 双重检查锁
       package dao;
public class Singleton {
  //Java提供了volatile关键字来保证多线程可见性,当其中一个线程对某一个值修改后,其他线程能看到 
    private volatile static Singleton singleton;
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {//使用了synchronized 同步代码块
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
	/*
          通过enum关键字来实现枚举,在枚举中需要注意的有:
        1. 枚举中的属性必须放在最前面,一般使用大写字母表示
        2. 枚举中可以和java类一样定义方法
        3. 枚举中的构造方法必须是私有的
        4. 通过一个java类来模拟枚举的功能:
        5. 
 单元素的枚举类型已经成为实现Singleton的最佳实践。 */
 

public class Person {
	private Person() {};
	// 这里有几个原因关于为什么在Java中宁愿使用一个枚举量来实现单例模式:
	/*
         1、 自由序列化;
         2、 保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量);
         3、 线程安全;
	 */
	// 懒汉式枚举实现 Singleton
	public enum Singleton {// 相当于Singleton类
		INSTANCE;// 枚举里的属性相当于Singleton的实例
		private Person instance;
		private Singleton() {// 私有构造函数
			instance = new Person();// 在构造函数中完成实例化操作
		}
		public Person getInstance() {// 提供公有方法对其访问
			return instance;
		}
	}
	// 使用Singleton.INSTANCE.getInstance();来调用
}

猜你喜欢

转载自blog.csdn.net/ljh_learn_from_base/article/details/72802777