• 浅谈单例模式


    饿汉式

    package com.dwz.concurrency2.chapter1;
    /**
     * 饿汉式
     */
    public class SingletonObject2 {
        /*
         * can't lazy load.
         */
        private static final SingletonObject2 instance = new SingletonObject2();
        
        private SingletonObject2() {
            //empty
        }
        
        public static SingletonObject2 getInstance() {
            return instance;
        }
    }

    缺点:不能进行懒加载,可能会造成资源浪费

    懒汉式

    package com.dwz.concurrency2.chapter1;
    /**
     * 懒汉式(双重检查)
     */
    public class SingletonObject1 {
        private static SingletonObject1 instance;
        
        private SingletonObject1() {
            //empty
        }
        
        //double check
        //解决了懒加载问题和线程安全问题
        public static SingletonObject1 getInstance() {
            if(null == instance) {
                synchronized (SingletonObject1.class) {
                    if(null == instance) {
                        instance = new SingletonObject1();
                    }
                }
            }
            //会出现初始化异常问题,instance还在重排序,未初始化完成,此时已不是null,就被return
            return instance;
        }
    }

    缺点:不能保证线程绝对安全,尤其是new SingletonObject1()中加载比较重的v资源时

    介绍三种比较优雅的v单例模式:

    1.双重检查改良版

    package com.dwz.concurrency2.chapter1;
    /**
     * 懒汉式(双重检查-线程安全)
     */
    public class SingletonObject3 {
        //volatile可以保证内存可见性,有序性,不让jvm自作主张去优化
        //可以保证之前的写操作完成
        private static volatile SingletonObject3 instance;
        
        private SingletonObject3() {
            //empty
        }
        
        //double check add volatile
        public static SingletonObject3 getInstance() {
            if(null == instance) {
                synchronized (SingletonObject3.class) {
                    if(null == instance) {
                        instance = new SingletonObject3();
                    }
                }
            }
            return instance;
        }
    }

    缺点:虽然解决了线程安全问题,但是jvm的一些底层优化操作被摒弃

    2.holder方式

    package com.dwz.concurrency2.chapter1;
    /**
     * holder方式(推荐使用)
     * 懒加载、线程安全、效率高
     */
    public class SingletonObject4 {
        
        private SingletonObject4() {
            
        }
        
        private static class InstanceHolder {
            private final static SingletonObject4 instance = new SingletonObject4();
        }
        
        public static SingletonObject4 getInstance() {
            return InstanceHolder.instance;
        }
    }

    3.枚举法

    package com.dwz.concurrency2.chapter1;
    
    import java.util.stream.IntStream;
    
    /**
     * 枚举法:(大师推荐)
     * 天生就是线程安全的,构造函数只被加载一次
     */
    public class SingletonObject5 {
        
        private SingletonObject5() {
            
        }
        
        private enum Singleton {
            INSTANCE;
            
            private final SingletonObject5 instance;
            
            Singleton() {
                instance = new SingletonObject5();
            }
            
            public SingletonObject5 getInstance() {
                return instance;
            }
        }
        
        public static SingletonObject5 getInstance() {
            return Singleton.INSTANCE.getInstance();
        }
        
        public static void main(String[] args) {
            IntStream.rangeClosed(1, 100)
                     .forEach(i-> new Thread(String.valueOf(i)) {
                         @Override
                        public void run() {
                             System.out.println(SingletonObject5.getInstance());
                        }
                     }.start());
        }
    }
  • 相关阅读:
    读书笔记之:数据结构,算法与应用(3)
    C++中的虚函数继承与虚继承
    读书笔记之:Effective STL
    C++虚函数及虚函数表解析
    类中的常量, const对象和成员函数
    读书笔记之:Boost程序库完全开发指南(Ch14)
    读书笔记之:C++探秘——68讲贯通C++
    读书笔记之:Boost程序库完全开发指南(ch516)
    配置java的环境变量
    查询并杀死死锁
  • 原文地址:https://www.cnblogs.com/zheaven/p/12097208.html
Copyright © 2020-2023  润新知