zoukankan      html  css  js  c++  java
  • 单例模式作用特点及常见的单例模式分析(6种单例模式分析)

    单例模式:

    1. 即在整个生命周期中,对于该对象的生产始终都是一个,不曾变化。
    2. 保证了一个类仅有一个实例,并提供一个访问它的全局访问点。

    作用:

    1. 在要求线程安全的情况下,保证了类实例的唯一性,线程安全。
    2. 在不需要多实例存在时,保证了类实例的单一性。不浪费内存。

    特点:

    1. 公有的方法获取实例,
    2. 私有的构造方法,
    3. 私有的成员变量。

    一,饿汉式
    * @Description 饿汉式单例
         * 饿汉式单例关键在于singleton作为类变量并且直接得到了初始化,即类中所有的变量都会被初始化
         * singleton作为类变量在初始化的过程中会被收集进<clinit>()方法中,该方法能够百分之百的保证同步,
         * 但是因为不是懒加载,singleton被加载后可能很长一段时间不被使用,即实例所开辟的空间会存在很长时间
         * 虽然可以实现多线程的唯一实例,但无法进行懒加载;

    package com.liruilong.singleton;
     
    /**
     * @Author: Liruilong
     * @Date: 2019/7/20 17:55
     */
     
    // final 不允许被继承
    public final class Singleton {
        // 实例变量
        private byte[] bate = new byte[1024];
        // 私有的构造函数,即不允许外部 new
        private Singleton(){ }
        private  static final Singleton singleton1 = new Singleton();
        public static  Singleton getInstance1(){
            return singleton1;
        }

    二,懒汉式

    * @Description 懒汉式单例模式
         * 可以保证懒加载,但是线程不安全
         * 当有两个线程访问时,不能保证单例的唯一性

    package com.liruilong.singleton;
     
    /**
     * @Author: Liruilong
     * @Date: 2019/7/20 17:55
     */
     
    // final 不允许被继承
    public final class Singleton {
        // 实例变量
        private byte[] bate = new byte[1024];
        // 私有的构造函数,即不允许外部 new
        private Singleton(){ }
     
        private static  Singleton singleton =null;
    public static Singleton getInstance(){ if (singleton == null) { singleton = new Singleton(); } return singleton; }

    三,懒汉式加同步方法
    * @Description 懒汉式+同步方法单例模式
         * 即能保证懒加载,又可以保证singleton实例的唯一性,但是synchronizeed关键字的排他性导致
         * getInstance0()方法只能在同一时间被一个线程访问。性能低下。

    package com.liruilong.singleton;
     
    /**
     * @Author: Liruilong
     * @Date: 2019/7/20 17:55
     */
     
    // final 不允许被继承
    public final class Singleton {
        // 实例变量
        private byte[] bate = new byte[1024];
        // 私有的构造函数,即不允许外部 new
        private Singleton(){ }
    
        private static  Singleton singleton =null;
    public static synchronized Singleton getInstance0(){ if (singleton == null) { singleton = new Singleton(); } return singleton; }

    四,双重效验锁单例
    * @Description 双重校验锁单例(Double-Check)+Volatile
         *  对懒汉-同步方法的改进,当有两个线程发现singleton为null时,只有一个线程可以进入到同步代码块里。
         *  即满足了懒加载,又保证了线程的唯一性
         *  不加volition的缺点,有时候可能会报NPE,(JVM运行指令重排序)
         *  有可能实例对象的变量未完成实例化其他线程去获取到singleton变量。
         *  未完成初始化的实例调用其方法会抛出空指针异常。

    package com.liruilong.singleton;
     
    /**
     * @Author: Liruilong
     * @Date: 2019/7/20 17:55
     */
     
    // final 不允许被继承
    public final class Singleton {
        // 实例变量
        private byte[] bate = new byte[1024];
        // 私有的构造函数,即不允许外部 new
        private Singleton(){ }
     
        private  static volatile Singleton singleton2 = null;
    public static Singleton getInstance4() { if (singleton2 == null){ synchronized (Singleton.class){ if (singleton2 ==null){ singleton2 = new Singleton(); } } } return singleton2; }

    五,静态内部类单例
     * @Description 静态内部类的单例模式
         * 在Singleton类初始化并不会创建Singleton实例,在静态内部类中定义了singleton实例。
         * 当给静态内部类被主动创建时则会创建Singleton静态变量,是最好的单例模式之一
       

    package com.liruilong.singleton;
     
    /**
     * @Author: Liruilong
     * @Date: 2019/7/20 17:55
     */
     
    // final 不允许被继承
    public final class Singleton {
        // 实例变量
        private byte[] bate = new byte[1024];
        // 私有的构造函数,即不允许外部 new
        private Singleton(){ }
     
        private  static class Singtetons{
    private static Singleton SINGLETON = new Singleton(); /* static { final Singleton SINGLETON = new Singleton(); }*/ } public static Singleton getInstance2(){ return Singtetons.SINGLETON; }

    六,枚举类单例 

     * @Description 基于枚举类线程安全
         * 枚举类型不允许被继承,同样线程安全的,且只能被实例化一次。

    package com.liruilong.singleton;
     
    /**
     * @Author: Liruilong
     * @Date: 2019/7/20 17:55
     */
     
    // final 不允许被继承
    public final class Singleton {
        // 实例变量
        private byte[] bate = new byte[1024];
        // 私有的构造函数,即不允许外部 new
        private Singleton(){ }
    
        private enum Singtetonss {
            SINGTETONSS; //实例必须第一行,默认 public final static修饰
            private Singleton singleton;
     
            Singtetonss() { //构造器。默认私有
                this.singleton = new Singleton();
            }
            public static Singleton getInstance() {
                return SINGTETONSS.singleton;
            }
        }
        public static  Singleton getInstance3(){
            return Singtetonss.getInstance();
        }

    原本是我笔记里的,摘了出来,面试的时候看,

    更多见 ----》《Java并发编程详解》读书笔记

  • 相关阅读:
    HDU 4472 Count DP题
    HDU 1878 欧拉回路 图论
    CSUST 1503 ZZ买衣服
    HDU 2085 核反应堆
    HDU 1029 Ignatius and the Princess IV
    UVa 11462 Age Sort
    UVa 11384
    UVa 11210
    LA 3401
    解决学一会儿累了的问题
  • 原文地址:https://www.cnblogs.com/liruilong/p/12236742.html
Copyright © 2011-2022 走看看