• 设计模式课程 设计模式精讲 8-4 单例设计模式-静态内部类-基于类初始化的延迟加载解决方案及原理解析


    1    原理解析

    1.0  课程地址

    1.1  如何实现让后边线程看不到前边线程是否有序列化呢(综合上节看)

    1.2  原理

    1.3  5种初始化方法

    1.4  单例类必须要有私有构造方法

    2    代码演练

    2.1  代码演练1

    1    原理解析
    1.1  如何实现让后边线程看不到前边线程是否有重排序呢(综合上节看)

    参考2.1,使用基于类初始化的方案,使用静态内部类的单例模式来解决。

    1.2  原理

    jvm 在类的初始化阶段,也就是class被加载后并且被线程使用之前,都是类的初始化阶段。在这个阶段,会执行类的初始化。在此期间,jvm会获取锁,这个锁会同步多个线程对一个类的初始化。

    基于上述特性,我们可以实现基于静态内部类并且线程安全的延迟初始化方案。基于类初始化的延迟加载解决方案。(即非构造线程无法看到重排序)(主要是因为类初始化是会上锁的,所以即使多线程去调用,只会有一个线程拿到锁去初始化,)

    如下图:线程1看不到线程0是否发生了重排序

    1.3  5种情况下,一个类(泛指,包括interface)会被立即初始化

    a  a类型实例被创建(new方法)

    b  a类声明的静态方法被调用

    c  a类声明的静态成员被赋值

    d  a类声明的静态成员被使用,并且该成员不是常量成员

    e  a类如果是顶级类,并且在类中有嵌套的断言语句

    1.4  单例类必须要有私有构造方法

    同上,必须要有,没有的话可以被外部类实例化

    2    代码演练
    2.1  代码演练1

    线程类:

    package com.geely.design.pattern.creational.singleton;
    
    /**
     * 注:该类为线程类,调用LazySingleton
     */
    public class T implements Runnable{
    
        /*@Override
        public void run() {
            LazySingleton lazySingleton = LazySingleton.getInstance();
            System.out.println(Thread.currentThread().getName()+"==="+lazySingleton);
    
        }*/
    
        /*@Override
        public void run() {
            LazyDoubleCheckSingleton lazyDoubleCheckSingleton = LazyDoubleCheckSingleton.getInstance();
            System.out.println(Thread.currentThread().getName()+"==="+lazyDoubleCheckSingleton);
        }*/
    
        @Override
        public void run() {
            StaticInnerClassSingleton staticInnerClassSingleton = StaticInnerClassSingleton.getInstance();
            System.out.println(Thread.currentThread().getName()+"==="+staticInnerClassSingleton);
        }
    }

    静态内部类:

    package com.geely.design.pattern.creational.singleton;
    
    public class StaticInnerClassSingleton {
        /**
         * 静态内部类
         * 自己容易犯的错误:静态内部类不要加(),不是方法。
         */
        private static class InnerClass{
            private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton();
        }
    
        public static StaticInnerClassSingleton getInstance(){
            //这里如何进行初始化呢?
            return InnerClass.staticInnerClassSingleton;
        }
    
        /**
         * 注意一定要写私有的构造函数,否则的话容易被外部类实例化该类
         */
        private StaticInnerClassSingleton(){
            
        }
    }
  • 相关阅读:
    ZCMU训练赛-H(模拟)
    ZCMU训练赛-B(dp/暴力)
    ZCMU训练赛-A(模拟)
    HDU 2045 LELE的RPG难题(递推)
    HDU 2044 一只小蜜蜂(递归)
    HDU 2050 折线分割平面(转)
    对递归的理解归纳(转)
    漫谈递归思想(转)
    2017中南大学暑期集训day1 : debug&STL-A
    探寻宝藏--河南省第六届大学生程序设计竞赛
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/11368730.html
Copyright © 2020-2023  润新知