单例设计模式(Singleton)
工厂模式说完,这里我再说一下单例模式,这里只是简单的总结一下,说一下概念什么的,具体的单例模式可以看我之后的blog(应该会写的吧,我也不确定哈哈哈 )
好,不开玩笑了,既然大家都是学java的,必然听过这个单例模式。很多公司都会让你手撕一段单例模式,可见单例模式的重要了,我以前面试的时候,这个东西都是写烂的玩意儿了,但是有一次一个公司问我,你说说为什么要使用单例模式,说实话我直接懵逼了,确实之前一直没有考虑过这个事情。相信很多初学者也很好奇为什么使用,这里我把这个问题摆到最前面解决一下。
什么是单例模式
在此之前我先介绍一下单例模式吧:单例模式是确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
※为啥要用单例模式※(这里借鉴百度百科)
对于系统中的某些类来说,只有一个实例很重要的,例如:
-
一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务
-
一个系统只能有一个窗口管理器或文件系统,如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源
-
如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态(系统需要保证数据正确性),因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。
nice!懂了吧!单例模式是多么的重要!
然后大家要知道,单例模式有两种创建方法:
- 饿汉式
- 懒汉式
一:单例模式 之 饿汉式
“饿汉”,看名字你就应该知道这玩意是有多饥渴,就特别着急,给他一碗饭,一上来就立马要吃,这就是饿汉式的精髓!
public class Singleton {
private static Singleton instance = new Singleton();private Singleton(){
}public static Singleton getInstance(){
return instance;}
}
这里我感觉得解释一下这段代码了:首先定义一个类叫做Singleton(单个的),然后正如饿汉式所言,饿的不行了,赶紧一上来就new了一个静态对象,名字叫instance。然后来了一个私有的构造函数,最后有一个获取实例化对象的函数getInstance()。这就是单例模式。
我们可以新建一个TestCase测试方法,新建两个对象来比较一下:
Singleton c1 = Singleton.getInstance();
Singleton c2 = Singleton.getInstance();
System.out.println(c1==c2);
这段代码是为了比较一下两个对象是不是一个对象,单例模式是不是人如其名,检测是不是真的只创建了一个对象。运行出来的结果我就不截图了,答案是true,这意味着什么?这意味着这两个对象的hashcode是一样的,简单来说就是一个对象!神奇了吧~
二:单例模式 之 懒汉式
你看看,开发人员和翻译人员多牛X,懒汉式也是人如其名,他快懒死了,他的心路历程是这样的:“不就是个实例化对象吗!瞅你们着急的,你们之前有没有实例化对象啊?让我看一看,奥!没有实例化啊,来来来,大爷给你实例化一个(或者:啥?你已经实例化了?那你叫我干啥,滚犊子!)”
这段话就已经凸显出了懒汉式和饿汉式的区别了,饿死鬼是一上来就要实例化,生怕忘了。但是这懒汉式的死宅男,只有在需要实例化的时候才慢吞吞的实例化,不仅这样,他还要加一个判断语句,判断一下之前有没有实例化过。下面是懒汉式的代码:
public class Singleton {
private static Singleton instance = null;private Singleton(){
}public static Singleton getInstance(){
if (instance==null){
instance = new Singleton();}return instance;}
}
可以看出,两种方式差别不大,但是懒汉式容易出问题,这里不赘述了,之后我会详细剖析这个问题的,这个问题主要还是表现在多线程那一块,加一个锁就可以解决问题。