• 设计模式 单例模式


    一、使用场景

      系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

    二、单例模式实现的要点:

      1、私有、静态的单例对象

      2、构造函数私有化

      3、提供对外的公共访问方法,以获得单例对象

    三、单例模式有三种实现

      1、饱汉式(用的时候实例化)

    public class SingletonDemo {
        // 有的会加final修饰符(更为严谨),添加final修饰符之后,指向的引用不能再做更改。
        // 这是final的用法:final成员变量表示常量,只能被赋值一次,赋值后值不能再改变。
        private static final SingletonDemo singletonInstance = new SingletonDemo();
    
        private SingletonDemo() {  
        }
    
        public static SingletonDemo getSingletonInstance() {
            return singletonInstance;
        }
    }

      

      2、饿汉式(初始化已准备好)

    public class SingletonDemo {
        // 这个就不能加final,因为要在其他地方给他再次赋值呢。
        // 加了final,那就默认一直是null啦,而且还不能再次给此属性赋值。
        // 此属性是静态,那么就是共享数据,多线程并发操作共享数据是有可能的。那么就会出现下面的线程不安全现象。
        private static SingletonDemo singletonInstance;
    
        private SingletonDemo() {
        }
    
        public static SingletonDemo getSingletonInstance() {
            if (singletonInstance == null) {
                // 在这个地方,多线程的时候,
                // 可能A线程挂起,此属性还是null,那么B线程可能也判断条件OK也进来啦。
                // 然后A线程可以执行的时候就会new个对象,线程B也会new个对象。
                // 就不能保证内存的唯一性。也就是线程不安全
                singletonInstance = new SingletonDemo();
            }
            return singletonInstance;
        }
    
        /// **
        // * 为了应对上述的不安全,可以简单的如下操作给方法添加[synchronized],使之成为同步函数。
        // * 但是:
        // * 在很多线程的情况下,就每个线程访问都得判断锁,效率就是问题。所以,才有后面的[双重锁形式]
        // */
        // public static synchronized SingletonPattern2 getSingletonInstance() {
        // if (singletonInstance == null) {
        // singletonInstance = new SingletonPattern2();
        // }
        // return singletonInstance;
        // }
    }

      3、双重锁

    /**
     * 双重锁形式
     * 这个模式将同步内容下放到if内部,提高了执行的效率,不必每次获取对象时都进行同步,
     * 只有第一次才同步,创建了以后就没必要了。避免土豪模式下创建单例,可能存在的线程不安全问题。
     * <p>
     * Created by lxk on 2017/3/23
     */
    public class SingletonDemo {
        
        private static SingletonDemo singletonInstance;
    
        private SingletonDemo() {
        }
    
        /**
         * 静态方法同步的时候,使用的锁,就不能是this,而是类.class
         */
        public static SingletonDemo getSingletonInstance() {
            if (singletonInstance == null) {
                // 这个地方可能有多个线程,在这排队,ABCD..。
                synchronized (SingletonDemo.class) {
                    if (singletonInstance == null) {
                        // 假设第一次A线程走到这,然后,呈挂起状态。这个时候,单例对象还未创建;
                        // 假设此时,B线程也来了判断单例对象==null成立,但是,因为A线程已经给里层的if判断上锁,所以,B只能在外等着。
                        // 假设A线程被唤醒,那么,单例就会下面语句赋值,单例对象就创建啦。然后释放锁。B就可以进来啦。
                        // B线程进来之后,先判断单例对象是否为null,发现已经不是null啦,那么就不需要创建啦。
                        // CD线程同样,
                        // 再往后面来的,第一个if就进不来啦,那就不会判断锁了。
                        singletonInstance = new SingletonDemo();
                    }
                }
            }
            return singletonInstance;
        }
    }

          转载自:http://blog.csdn.net/qq_27093465/article/details/50978916

  • 相关阅读:
    14-补充内容:MySQl创建用户和授权
    15-可视化工具Navicat的使用
    11-数据的增删改
    12-单表查询
    09-完整性约束
    10-外键的变种 三种关系
    07-数据类型
    08-数据类型(2)
    Mysql 基本语法
    E. K-periodic Garland
  • 原文地址:https://www.cnblogs.com/zxguan/p/7825126.html
Copyright © 2020-2023  润新知