zoukankan      html  css  js  c++  java
  • Java 单例模式,Java Singleton单例模式

    Java 单例模式,Java Singleton单例模式

    ================================

    ©Copyright 蕃薯耀 2021-04-14

    https://www.cnblogs.com/fanshuyao/

    一、单例模式 - 饿汉模式

    * 单例模式-饿汉模式
    * 优化:代码简单,线程安全
    * 缺点:类初始化时,直接创建了对象,增加了内存的使用

    /**
     * 单例模式-饿汉模式
     * 优化:代码简单,线程安全
     * 缺点:类初始化时,直接创建了对象,增加了内存的使用
     *
     */
    public class SingletonHungry {
    
        /**
         * 创建对象,使用static final修饰
         */
        private static final SingletonHungry singletonHungry = new SingletonHungry();
        
        /**
         * 私有化(private)无参数的构造方法,不会被外部类创建对象
         */
        private SingletonHungry() {}
        
        /**
         * 返回单例对象的方法
         * @return
         */
        public static SingletonHungry getInstance() {
            return singletonHungry;
        }
        
        
    }

    单例模式-饿汉模式测试代码:

    public class Main {
        
        public static void singletonHungry() {
            for(int i=0; i<15; i++){
                new Thread(()-> {
                    System.out.println(SingletonHungry.getInstance() == SingletonHungry.getInstance());
                }).start(); 
            }
        }
        
        public static void main(String[] args) {
            singletonHungry();
            
        }
    
    }

    二、单例模式 - 懒汉模式 - 双重判断

    * 单例模式-懒汉模式
    * 优点:性能好,不直接创建对象,需要时才创建
    * 缺点:双重判断,代码复杂

    /**
     * 单例模式-懒汉模式
     * 优点:性能好,不直接创建对象,需要时才创建
     * 缺点:双重判断,代码复杂
     *
     */
    public class SingletonLazy {
    
        /**
         * 声明对象,使用static,不使用final修饰,要使用volatile修饰,volatile避免指令重排序的问题
         */
        private static volatile SingletonLazy singletonLazy;
        
        /**
         * 私有化(private)无参数的构造方法,不会被外部类创建对象
         */
        private SingletonLazy() {}
        
        
        /**
         * 返回单例对象的方法
         * 双重判断
         * 在创建对象时加synchronized关键字修饰,不是整个方法,性能更加好
         * 
         * @return
         */
        public static SingletonLazy getInstance() {
            
            if(singletonLazy == null) {
                synchronized (SingletonLazy.class) {
                    if(singletonLazy == null) {
                        singletonLazy = new SingletonLazy();
                    }
                }
            }
            return singletonLazy;
        }
    }

    测试代码:

    public class Main {
    
        public static void singletonLazy() {
            for(int i=0; i<15; i++){
                new Thread(()-> {
                    System.out.println(SingletonLazy.getInstance() == SingletonLazy.getInstance());
                }).start();
            }
        }
        
    
        public static void main(String[] args) {
            singletonLazy();
        }
    
    }

    存在问题:

    如果不使用双重判断和synchronized关键字修饰,会出问题:

        public static SingletonLazy getInstance() {
            
            if(singletonLazy == null) {
                singletonLazy = new SingletonLazy();
            }
            
            return singletonLazy;
        }

    测试结果:存在 false

    true
    true
    true
    true
    true
    true
    true
    true
    true
    false
    true
    true
    true
    true
    true

    如下图所示:

    (时间宝贵,分享不易,捐赠回馈,^_^)

    ================================

    ©Copyright 蕃薯耀 2021-04-14

    https://www.cnblogs.com/fanshuyao/

    今天越懒,明天要做的事越多。
  • 相关阅读:
    缓存在高并发场景下的常见问题
    如何提高缓存命中率
    修改或隐藏nginx的版本号
    centos7使用docker安装zabbix
    Handsontable 新增一行 默认值
    java保留有效数字
    Handsontable通用方法
    handsontable插件事件
    handsontable常规配置的中文API
    handsontable的核心方法
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/14656775.html
Copyright © 2011-2022 走看看