单例模式(Singleton Pattern)

单例模式(Singleton Pattern)

目的:保证一个类仅有一个实例,并提供一个访问它打的全局访问点。
主要解决:一个全局使用的类被频繁的创建于销毁。
何时使用:当你想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
使用场景:
1.产生唯一序列号。
2.web中的计数器,不用每次刷新都在数据库增加一次,用单例存储。
3.创建的一个对象需要消耗的资源过多,比如I/O与数据库的连接等。
注意事项:getInstance()方法中需要使用同步锁synchronized(Singleton.class)防止多线程同时进入造成instance被多次实例化。
优点:
1.在内存里只有一个实例,减少了内存的开销,尤其是是的频繁的创建和销毁实例。
2.避免对资源的多重占用。(写文件操作)
缺点:没有接口,不能继承,与单一职责原则冲突,一个类只关心内部逻辑,而不关心外面怎么样来实例化。

创建方式:饿汉式+懒汉式两种方式

饿汉式:程序初始化的时候就创建了类的对象,需要的时候就直接返回对象实例。

 1 /**
 2      * 饿汉式
 3      */
 4     static class Singleton1 {
 5         private static final Singleton1 s = new Singleton1();
 6 
 7         private Singleton1() {
 8         }
 9 
10         public static Singleton1 getInstance() {
11             return s;
12         }
13     }

懒汉式:在真正需要实例化对象的时候才进行创建对象。

 1 /**
 2      * 懒汉式
 3      */
 4     static class Singleton2 {
 5         private static Singleton2 s = null;
 6 
 7         private Singleton2() {
 8         }
 9 
10         public static Singleton2 getInstance() {
11             if (s == null) {
12                 s = new Singleton2();
13             }
14             return s;
15         }
16     }

以上两种方式是只适用于单线程,这两种方式在多线程的时候是非线程安全的。

为了在多线程的情况下使用

1. 在懒汉式方式下添加synchronized关键字,形成双检锁方式。

 1 /**
 2      * 多线程环境下的懒汉式单例模式(DCL,双检锁实现)
 3      */
 4     static class Singleton3 {
 5         private static Singleton3 s = null;
 6 
 7         private Singleton3() {
 8         }
 9 
10         public static Singleton3 getInstance() {
11             if (s == null) {
12                 synchronized (Singleton3.class) {
13                     if (s == null) {
14                         s = new Singleton3();
15                     }
16                 }
17             }
18             return s;
19         }
20     }

2. 在双检锁的基础上添加volatile关键字,形成双检锁+volatile的方式,这种方式主要是防止指令的重排序。

 1 /**
 2      * 多线程环境下的懒汉式单例模式(DCL,双检锁+volatile实现)
 3      * 加入了volatile变量来禁止指令重排序
 4      */
 5     static class Singleton4 {
 6         private static volatile Singleton4 s = null;
 7 
 8         private Singleton4() {
 9         }
10 
11         public static Singleton4 getInstance() {
12             if (s == null) {
13                 synchronized (Singleton4.class) {
14                     if (s == null) {
15                         s = new Singleton4();
16                     }
17                 }
18             }
19             return s;
20         }
21     }

单例模式以上四种方式的完整代码如下:

 1 /**
 2  * @author: wooch
 3  * @create: 2020/02/13
 4  */
 5 
 6 /**
 7  * 单例模式
 8  * 分为 饿汉式和懒汉式两种
 9  */
10 public class Singleton {
11     /**
12      * 饿汉式
13      */
14     static class Singleton1 {
15         private static final Singleton1 s = new Singleton1();
16 
17         private Singleton1() {
18         }
19 
20         public static Singleton1 getInstance() {
21             return s;
22         }
23     }
24 
25     /**
26      * 懒汉式
27      */
28     static class Singleton2 {
29         private static Singleton2 s = null;
30 
31         private Singleton2() {
32         }
33 
34         public static Singleton2 getInstance() {
35             if (s == null) {
36                 s = new Singleton2();
37             }
38             return s;
39         }
40     }
41 
42     /**
43      * 多线程环境下的懒汉式单例模式(DCL,双检锁实现)
44      */
45     static class Singleton3 {
46         private static Singleton3 s = null;
47 
48         private Singleton3() {
49         }
50 
51         public static Singleton3 getInstance() {
52             if (s == null) {
53                 synchronized (Singleton3.class) {
54                     if (s == null) {
55                         s = new Singleton3();
56                     }
57                 }
58             }
59             return s;
60         }
61     }
62 
63         /**
64          * 多线程环境下的懒汉式单例模式(DCL,双检锁+volatile实现)
65          * 加入了volatile变量来禁止指令重排序
66          */
67         static class Singleton4 {
68             private static volatile Singleton4 s = null;
69 
70             private Singleton4() {
71             }
72 
73             public static Singleton4 getInstance() {
74                 if (s == null) {
75                     synchronized (Singleton4.class) {
76                         if (s == null) {
77                             s = new Singleton4();
78                         }
79                     }
80                 }
81                 return s;
82             }
83         }
84 }
View Code
原文地址:https://www.cnblogs.com/baishouzu/p/12304559.html