23种设计模式-单例模式

一.单例设计模式介绍

单例设计模式,从字面上理解就是单个实例。在我们工作中应该会经常用到单例模式,他是我们接触和使用比较多的设计模式之一了。
在spring中我们创建bean的时候配置会选择单例还是多例,这里面的单例就是本章说的单例。

什么是单例,举个栗子古代正常一个朝代只有一个皇帝,不会出现一朝多帝的情况,如果我们项目中遇到这种场景皇帝的对象就可以使
用单例来实现,因为从始到终有且只有一个皇帝出现这种情况我们就可以称为单例。

二.单例设计模式几种写法
1.懒汉式,线程不安全   

代码如下
 1 public class Singleton {  
 2        private static Singleton instance;  
 3        private Singleton (){}    
 4        public static Singleton getInstance() {  
 5         if (instance == null) {  
 6            instance = new Singleton();  
 7         }  
 8         return instance;  
 9        }  
10     } 
View Code
上面代码多线程情况下,A线程进入判断为null 进来然后返回这种情况是正确的。当线程B和线程A同时进来后,都判断为null就会两个返
回不同的实例。


2.懒汉式,线程安全
代码如下
 1 public class Singleton {  
 2            private static Singleton instance;  
 3            private Singleton (){}  
 4            public static synchronized Singleton getInstance() {  
 5            if (instance == null) {  
 6                instance = new Singleton();  
 7            }  
 8            return instance;  
 9            }  
10        }  
View Code
上面代码不管是否多线程都是线程安全的,因为我们加了synchronized关键字。虽然线程安全了,但是synchronized关键字在并发大多线程的
情况下会影响效率,所以此写法用的比较少。

3.饿汉式

代码如下
1 public class Singleton {  
2            private static Singleton instance = new Singleton();  
3            private Singleton (){}  
4            public static Singleton getInstance() {  
5             return instance;  
6            }  
7        }  
View Code
上面代码通过静态方法和属性使得线程安全同时也实现了我们所需,而且效率在多线程高并发下也不会受影响。
4.双检锁/双重校验锁(DCL,即 double-checked locking)   
代码如下
 1 public class Singleton {  
 2            private volatile static Singleton singleton;  
 3            private Singleton (){}  
 4            public static Singleton getSingleton() {  
 5            if (singleton == null) {  
 6                synchronized (Singleton.class) {  
 7                    if (singleton == null) {  
 8                        singleton = new Singleton();  
 9                    }  
10                }  
11            }  
12            return singleton;  
13            }  
14        } 
View Code
代码中我们看到两次判断singleton==null,还用到了synchronized 关键字代码实现比较复杂,所以不推荐使用。

5. 登记式/静态内部类
代码如下
1 public class Singleton {  
2            private static class SingletonHolder {  
3            private static final Singleton INSTANCE = new Singleton();  
4            }  
5            private Singleton (){}  
6            public static final Singleton getInstance() {  
7            return SingletonHolder.INSTANCE;  
8            }  
9         }
View Code
这种方式比双重锁的简单,是使用静态内部类和静态方法结合的方式。

6. 枚举
代码如下
1 public enum Singleton {  
2            INSTANCE;  
3            public void whateverMethod() {  
4            }  
5        }  
View Code
     
这种方式没有被广泛使用,是 Effective Java 作者 Josh Bloch 提出的方式,这种方式自动支持序列化,而且写起来简单。
posted @ 2019-07-22 19:09  海上翱翔  阅读(127)  评论(0)    收藏  举报