标签:加载 缺点 问题 单例 意义 zed str size 记忆
一:必要性
无论是在软件还是系统中,有时我们只需要某个东西出现一次,记得老师上课时提到的任务管理器,就是最典型的一个例子,任务管理器能告诉用户现在计算机里正在运行的程序的信息,试想一下如果能打开两个任务管理器,那么同步又是个大问题,虽然这个问题就不是个问题,没人愿意不明不白的看到两个任务管理器,如果有不同也不是用户的关注重点。而在记忆中,早期的windows就能打开很多任务管理器,现在想想这样是不太合理的。就算他们达成了同步一致的要求,那又有什么意义呢,都一样的东西,不过是浪费系统资源罢了。所以如何让一个类只有一个实例是很重要的。
二:定义
Ensure a class has a only one instance,and provide a globe point of access to it.即:确保一个类只有一个实例并且它自己能实例化自己并向整个系统提供这个实例。
三:实现方法
在java中有两种实现方式,分别是懒汉式和饿汉式。
1:饿汉式:顾名思义。说明人很饿,立马就要吃东西,
public class Singleton1 { // 私有构造 private Singleton1() {} private static Singleton1 single = new Singleton1(); // 静态工厂方法 public static Singleton1 getInstance() { return single; } }
构造方法为private,保证不能在类外实例化。直接创建好一个静态私有的单例实例对象,类外只能通过静态getinstance()获得唯一的实例对象。
2:懒汉式:不是很饿,饿的时候再创建。
1 public class Singleton2 { 2 3 // 私有构造 4 private Singleton2() {} 5 6 private static Singleton2 single = null; 7 8 public static Singleton2 getInstance() { 9 if(single == null){ 10 single = new Singleton2(); 11 } 12 return single; 13 } 14 }
同样私有构造方法保证不能在类外实例化。先不创建实例对象,赋值为null,只有调用getinstance()时才判断一下是不是有实例,如果没有则创建,有则直接返回实例。
四:并发问题
懒汉式加载在单线程时是没问题的,但当多线程并发时则会出现线程安全问题,原因是两个线程一起来都判断有没有实例,甚至是其中一个已经开始创建对象了,但对象初始化需要时间,这时另一个会判断没有实例,导致最后两个线程都创建了实例,单例失败!
解决方法:1:给getinstance加synchronized(效率低) 2:double-check,先判断有没有实例,如果没有则将方法加锁,如果有则直接返回实例,这样不用每次都执行同步快代码 3:用饿汉式加载
五:单例模式的优缺点
优点:1,防止资源浪费 2,减少性能开销 3,避免对资源的多重占用(指的是自己占用别人,不是自己占用) 4,设置访问点,优化共享资源的访问
缺点:1,一般没有接口,扩展困难,因为要自行实例,所以如果作为接口就不能被实例化了 2,对测试不利,如果单例模式未完成不能测试 3,与单一职责原理相悖,类应该只关心自己的事,而不是是否单例等其他业务逻辑。
标签:加载 缺点 问题 单例 意义 zed str size 记忆
原文地址:https://www.cnblogs.com/BlakeHair/p/10470306.html