zoukankan      html  css  js  c++  java
  • 单例模式(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
  • 相关阅读:
    lua学习之循环求一个数的阶乘
    lua元表学习
    ArrayList与List性能测试
    安卓开发线程
    安卓开发
    全局设置导航栏
    LinearLayout
    安卓布局ConstraintLayout
    安卓网络请求和图片加载
    安卓启动页面
  • 原文地址:https://www.cnblogs.com/baishouzu/p/12304559.html
Copyright © 2011-2022 走看看