单例模式的实现方式

单例模式的实现方式,第1张

单例模式的实现方式 一、概述

单例,就是整个程序有且仅有一个实例.该类负责创建自己的对象,同时确保只有一个对象被创建,常用于工具类的实现和创建对象需要消耗资源

  1. 将构造函数访问修饰符设置为private
  2. 通过一个静态方法或者枚举返回单例类对象
  3. 确保单例类的对象有且只有一个,特别是在多线程环境下
  4. 确保单例类对象在反序列化时不会重新构建对象
二、创建单例的6种方式
  • 饿汉式
  • 懒汉式
  • 双重校验锁
  • 静态内部类
  • 枚举
  • 容器
1、饿汉式

当程序启动或类被加载的时候,实例就就被创建。

public class SingleBean{
	//构造私有
	private SingleBean(){}
	
	private static SingleBean singleBean=new SingleBean();
	
	public static SingleBean getInstance(){
		return singleBean;
	}
} 
2、懒汉式

优点:单例对象在需要时,才会去构造
缺点:线程不安全的,多个线程调用,会产生多个单例对象

public class SingleBean{
	//构造私有
	private SingleBean(){}
	
	private static SingleBean singleBean=null;
	
	public static SingleBean getInstance(){
		if(null==singleton){
			singleBean=new Singleton();
		}
		return singleBean;
	}
3、双重校验锁

优点:可以解决线程安全问题,效率高

public class SingleBean{
	//构造私有
	private SingleBean(){}
	
	private static volatile SingleBean singleBean=null;
	
	public static SingleBean getInstance(){
		 if (singleBean == null) {
            synchronized (Singleton.class) {
                if (singleBean == null) {
                    singleBean = new Singleton();
                }
            }

        }
        return singleBean;
	}
} 

1.第一个判断,避免不要的实例。解决多线程情况下,不为空,直接返回,不需要再判断同步锁,提高性能
2.第二个判断,避免同步。在多线程情况下,一条线程a在执行new对象 *** 作,其他线程在锁外等待,不加判断的话,则线程a执行完new之后,会产出多个单例对象

4.静态内部类

优点:实现简单,懒加载,线程安全
缺点:增加一个静态内部类,apk文件增大

public class SingletonTest {
	
	private SingletonTest() {}
	
	private static class SingletonHolder{
		private static final SingletonTest instance = new SingletonTest();
	}
	
	public static SingletonTest getUniqueInstance() {
		return SingletonHolder.instance;
	}
}

5、枚举

优点:使用枚举是线程安全的,不用担心序列化和反射问题
缺点:枚举占用内存多一点,但枚举实例在日常开发是很少使用的,就是很简单以导致可读性较差。

public enum EnumSingleton{
	SINGLEBEAN;
	//doSomething 该实例支持的行为
      
    //可以省略此方法,通过Singleton.SINGLEBEAN进行 *** 作
    public static Singleton getInstance() {
        return Singleton.SINGLEBEAN;
    }
}
6、容器

优点:通过统一的接口获取 *** 作,隐藏了具体实现,降低了耦合度。

public class SingletonManager {
    private static Map objMap = new HashMap();

    public static void regsiterService(String key, Object instance) {
        if (!objMap.containsKey(key)) {
            objMap.put(key, instance);
        }
    }

    public static Object getService(String key) {
        return objMap.get(key);
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4659190.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存