Java设计模式之单例模式

前言

单例模式,顾名思义,即只产生唯一实例的设计模式。一个类只有一个实例,即一个类只有一个对象实例。

优点

1. 减少系统开销及资源消耗。

2. 设置全局访问点,优化共享资源的使用。

注:对于以上优点,我们可以拿Java配置读取举例,对于固定的配置文件,我们完全可以设计一个单例类,读取配置文件,而避免每次都读取文件造成的系统开销,同时也优化了配置文件的使用。

应用场景

  1. Servlet
  2. 开源框架Spring中的默认bean配置模式
  3. 数据库连接池
  4. 项目中对于配置文件的处理
    等等

写法分类

懒汉式单例模式(非线程安全)

1
2
3
4
5
6
7
8
9
10
11
12
public class Demo_Singleton_01 {  
private static Demo_Singleton_01 instance=null;
private Demo_Singleton_01(){

}
public static Demo_Singleton_01 getInstance(){
if(instance==null){
instance=new Demo_Singleton_01();
}
return instance;
}
}

说明:这种写法不常用,虽然实现了懒加载(lazy-loading),但未考虑线程安全问题,不适用于多线程情况。

懒汉式单例模式(线程安全)

1
2
3
4
5
6
7
8
9
10
11
12
public class Demo_Singleton_02 {  
private static Demo_Singleton_02 instance=null;
public static synchronized Demo_Singleton_02 getInstance(){
if(instance==null){
instance=new Demo_Singleton_02();
}
return instance;
}
private Demo_Singleton_02(){

}
}

说明:相对于demo1,这种写法实现了懒加载(lazy-loading),也考虑到线程安全问题,可适用于多线程情况。

饿汉式单例模式

1
2
3
4
5
6
7
8
9
public class Demo_Singleton_03 {  
private static final Demo_Singleton_03 instance=new Demo_Singleton_03();
private Demo_Singleton_03(){

}
public static Demo_Singleton_03 getInstance(){
return instance;
}
}

说明:饿汉式单例模式的明显缺点是无法实现懒加载,在类被创建后就创建了唯一实例。

饿汉式单例模式(变种)

1
2
3
4
5
6
7
8
9
10
11
12
public class Demo_Singleton_04 {  
private static Demo_Singleton_04 instance=null;
static{
instance=new Demo_Singleton_04();
}
private Demo_Singleton_04(){

}
public static Demo_Singleton_04 getInstance(){
return instance;
}
}

说明:可以看到这种方法和demo3的性质是一样的,只不过改为了静态块加载唯一实例。

静态内部类模式

1
2
3
4
5
6
7
8
9
10
11
public class Demo_Singleton_05 {  
private static class Singleton{
private static final Demo_Singleton_05 instance=new Demo_Singleton_05();
}
private Demo_Singleton_05(){

}
public static final Demo_Singleton_05 getInstance(){
return Singleton.instance;
}
}

说明:这种方法既可以实现懒加载,也能保证线程安全。

双重锁单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 public class Demo_Singleton_06 {  
private static volatile Demo_Singleton_06 instance=null;
private Demo_Singleton_06(){

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

说明:可以看出,双重锁单例模式只有在第一次创建对象的时候才同步,因为创建对象后就没必要了,(实例唯一)相比懒汉式,效率明显提高,相比饿汉式,不用在类加载的时候就创建实例,而是等到什么时候想调用的时候在创建实例。线程安全,效率高。

枚举法

1
2
3
4
5
6
public enum Demo_Singleton_07 {  
instance;
public void doSomething(){

}
}

说明:枚举法代码十分直观,线程安全,但是无法实现懒加载。

参考资料

  1. https://blog.csdn.net/goodlixueyong/article/details/51935526
  2. https://www.cnblogs.com/Ycheng/p/7169381.html

GitHub代码地址

https://github.com/JavaZWT/designPatterns




-------------文章结束啦 ~\(≧▽≦)/~ 感谢您的阅读-------------

您的支持就是我创作的动力!

欢迎关注我的其它发布渠道