博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式-Singleton
阅读量:6995 次
发布时间:2019-06-27

本文共 3297 字,大约阅读时间需要 10 分钟。

单例(Singleton)是一种常用的设计模式。在Java应用中,单例模式能保证在一个JVM中,该对象只有一个实例对象存在。这样的模式有几个好处:

1. 有些大型类的对象创建比较复杂,系统开销大,可以考虑使用单例模式。

2. 省去了new操作符,降低了系统内存的使用频率,减轻GC压力。

3. 有些类控制着整个业务流程,如果可以创建多个对象的话,系统就乱了。只有使用单例模式,才能保证核心引擎独立控制整个流程。

 

先写一个饿汉式的单例模式:这种模式的好处就是不会产生线程安全问题

1 private class Singleton {           2     private static Singleton instance = new Singleton(); 3     4     private Singleton() {}5 6     public static Singleton getInstance() {7         return instance;           8     }9 }

通过这个简单的代码,可以看出单例模式有以下特性:

1. 构造函数私有化:防止对象在外部被创建

2. 公有的获取实例的函数getInstance():可以从外部通过Singleton.getInstance()获取实例

3. 私有且静态的Singleton类型成员变量

本人认为饿汉式单例模式已经够用了,因为使用单例模式就为了使用它的实例对象,在类加载时创建和在使用时创建没有很大区别

 

下面介绍一下懒汉式单例模式:可能会有线程安全性问题

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

为解决线程安全问题,可以对方法加上synchronized,得到下面的单例模式:

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

此方式类似于:

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

但是,此方法由于每次调用getInstance()时都会访问一次锁(为对象加锁),但是实际的情况是只有第一次调用时才应该加锁,因此效率低下,可以使用两次判断(double check)方式提高锁效率:

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

此方法类似于:

1 public class Singleton {   2    3     private static Singleton instance = null;   4    5     private Singleton() {}   6  7     public static Singleton getInstance() {   8         if (instance == null) { 9             buildInstance();10         }11         return instance;  12     }13 14     private static synchronized void buildInstance() {15         if (instance == null) {  16             instance = new Singleton();  17         }18     }19 }

 

由于JVM内部的类加载机制能够保证当一个类被加载的时候,加载过程是线程互斥的。这样,我们可以使用内部类来维护单例的实现:当我们第一次调用getInstance()的时候,JVM能够帮我们保证instance只被创建一次,这样我们就不用担心线程安全问题。同时该方法只会在第一次调用的时候使用互斥机制,这样又解决了效率低的问题。这样我们可以得到下面的单例模式:

1 public class Singleton {   2    3     private Singleton() { }  4   5     private static class SingletonFactory {   6         private static Singleton instance = new Singleton();   7     }  8    9     public static Singleton getInstance() {  10         return SingletonFactory.instance;  11     } 12 }

 

追加:只有一个元素的枚举即是单例

1 public enum Singleton {2     SINGLETON3 }

 

转载于:https://www.cnblogs.com/joshua-aw/p/6025833.html

你可能感兴趣的文章