码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式系列--单例模式

时间:2020-05-03 20:42:23      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:catch   comment   function   ams   ant   安全   ring   ack   线程安全   

定义

确保一个类在任何情况下,如运行容器中,都只有一个实例,实现构造函数私有化,并提供一个全局访问点。

实现方式

1 、饿汉式
public class HungrySingleton {

	private static final HungrySingleton INSTANCE = new HungrySingleton();

	private HungrySingleton() {

	}

	public static HungrySingleton getInstance() {
		return INSTANCE;
	}
}


public class HungrySingletonB {

	private static final HungrySingletonB INSTANCE ;

	static{
		INSTANCE = new HungrySingletonB();
	}

	private HungrySingletonB() {

	}

	public static HungrySingletonB getInstance() {
		return INSTANCE;
	}
}

饿汉式是在类加载的时候实例化对象。

2、懒汉式
public class LazySingleton {

	private static LazySingleton INSTANCE = null;

	public LazySingleton() {
	}

	public static synchronized LazySingleton getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new LazySingleton();
		}
		return INSTANCE;
	}
}

懒汉式是在调用类的getInstance 方式时,实例化对象。由于考虑到多线程原因,需要在每次调用方法时,加上synchronized 同步锁,因此性能相对较低。

3、双重检测锁
public class DoubleCheckSingleton {
	private static volatile DoubleCheckSingleton INSTANCE = null;

	public DoubleCheckSingleton() {
	}

	public static DoubleCheckSingleton getInstance() {
		if (INSTANCE == null) {
			synchronized (DoubleCheckSingleton.class) {
				if (INSTANCE == null) {
					INSTANCE = new DoubleCheckSingleton();
				}
			}
		}
		return INSTANCE;
	}
}

双重检测锁是在调用getInstance时,先去检测有没有实例化对象,没有的话再实例化对象。考虑到多线程 ,实例变量使用 volatile 修饰 ,利用虚拟机对变量的可见性 和 synchronized 同步锁,确保实例化 唯一性。性能相对懒汉式较高。

4、静态内部类
public class StaticInnerSingleton {

	public StaticInnerSingleton() {
	}

	public static StaticInnerSingleton getInstance() {
		return InnerClass.INSTANCE;
	}

	private static class InnerClass {
		private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();
	}
}

静态内部类 是在首次调用 getInstance方法时,实例化内部类对象InnerClass。由于使用 final 修饰,所以是线程安全的。

5、枚举式
public enum EnumSingleton {
	INSTANCE;

	public static EnumSingleton getInstance() {
		return INSTANCE;
	}
}

枚举式 是在类初始化时,注册的单一实例化对象,所以也属于注册式单例实现。

6、容器式
public class ContainerSingleton {

	public ContainerSingleton() {
	}

	private static Map<String, Object> IOC = new ConcurrentHashMap<>();

	public static Object getBean(String className) {
		synchronized (IOC) {
			if (!IOC.containsKey(className)) {
				try {
					Class<?> aClass = Class.forName(className);
					Object o = aClass.newInstance();
					IOC.put(className, o);
				} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
		return IOC.get(className);
	}
}

容器式 也是采用懒汉式的实现方式,不同的是 容器式把实例化后的对象放在Map 容器中集中管理,也是注册式单利实现,Spring 的 IOC 就是这种实现方式。

7、本地线程式
public class ThreadLocalSingleton {

	private static final ThreadLocal<ThreadLocalSingleton> threadLocal = new ThreadLocal<ThreadLocalSingleton>() {
		[@Override](https://my.oschina.net/u/1162528)
		protected ThreadLocalSingleton initialValue() {
			return new ThreadLocalSingleton();
		}

	};

	public static ThreadLocalSingleton getInstance() {
		return threadLocal.get();
	}
}

本地线程式 是在 单个线程内 保证实例化对象的唯一性。

技术图片

推荐http://www.1994july.club/?cat=518

设计模式系列--单例模式

标签:catch   comment   function   ams   ant   安全   ring   ack   线程安全   

原文地址:https://www.cnblogs.com/vwvwvwgwg/p/12822863.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!