zoukankan      html  css  js  c++  java
  • Java设计模式之单例模式

      一、前言:

      转载需要注明出处: https://i.cnblogs.com/EditPosts.aspx?opt=1

      单例模式其实很早之前就已经接触过了,但都是为了应付面试或者是为了装X。每过一段时间后,又有些模糊不清了,也仿佛从来没有项目中使用过,但最近终于有它的用武之地了。

      二、单例模式的特点:

      • 单例类只能有一个实例
      • 单例类自己给自己创建一个实例,注意是唯一的一个实例
      • 单例类必须给其他对象提供这唯一的实例

      三、单例模式分类:

      • 懒汉模式

          懒汉模式即懒加载,第一次被调用前不实例化。对于创建实例代价大,且不一定会使用时,使用懒加载模式可以减少开销

      • 饿汉模式

          饿汉模式,在类加载的同时实例化对象

      四、实现单例模式的各种方法:

      • 线程不安全的懒汉模式
    public  class LazySingleton {
         private LazySingleton() {
    
        }
        private  static LazySingleton single;
         public  static LazySingleton getSinton(){
             if (single == null ){
                single = new LazySingleton();
            }
            return single;
        }
    }

        这种方法在单线程场景中,是安全的,但在多线程情况中,单例模式未必是单例模式,也就是存在线程安全问题。

      • 同步方法下的多线程
    public class LazySingleton {
        private LazySingleton() {
    
        }
        private static LazySingleton single;
        public static synchronized LazySingleton getSinton(){
            if(single == null){
                single = new LazySingleton();
            }
            System.out.println(Thread.currentThread().getName()+": "+single);
            return single;
        }
    }

        使用sychronized修饰获取实例对象的方法,这种方法可以保证线程安全,但效率不高,每个线程都需要来获取 对象锁。

      • 同步代码块的懒汉模式
    public class LazySingleton {
        private LazySingleton() {
    
        }
    
        private static LazySingleton single;
    
        public static LazySingleton getSinton() {
            if (single == null) {
                synchronized (LazySingleton.class) {
                    single = new LazySingleton();
                }
            }
            System.out.println(Thread.currentThread().getName() + ": " + single);
            return single;
            
        }
    }

        由同步方法想到同步代码块,但实际上,这种方法并不是线程安全。

        解释:两个线程A、B,A线程判断single是空的 ,当获取到锁后;B线程开始判断,发现single是空的;这时A线程又快人一步,创建了一个对象;线程B来了,获取到锁,也创建了一个对象。

      • 双重检查的懒汉  
    public class LazySingleton {
        private LazySingleton() {
    
        }
    
        private static LazySingleton single;
    
        public static LazySingleton getSinton() {
            if (single == null) {
                synchronized (LazySingleton.class) {
                    if(single== null){
                        single = new LazySingleton();
                    }
                }
            }
            System.out.println(Thread.currentThread().getName() + ": " + single);
            return single;
            
        }
    }

        针对同步代码块的懒汉,双重检查的懒汉可以说是最佳的,既保证了线程安全,又不需要每次都获取锁资源。(推荐双重检查懒汉)

      • 静态常量饿汉
    public class HungrySingleTon {
        
        private HungrySingleTon(){
        }
        
        private final static HungrySingleTon single = new HungrySingleTon();
        
        public static HungrySingleTon getInstance(){
            return single;
        }
    }

        无线程安全问题,缺点是类装在完成实例化,若一直未使用,会造成资源浪费。

      • 静态代码块饿汉模式
    public class HungrySingleTon {
    
        private HungrySingleTon() {
    
        }
    
        private static HungrySingleTon single;
    
        static {
            single = new HungrySingleTon();
        }
    
        public static HungrySingleTon getInstance() {
            return single;
        }
    }

          线程安全,与常量饿汉模式一样,若一直未被使用,会造成资源浪费。

      • 静态内部类
    public class HungrySingleTon {
    
        private HungrySingleTon() {
    
        }
    
        public  static HungrySingleTon getInstance() {
             return InnerClass.single;
        }
    
        private  static  class InnerClass {
             private  static  final HungrySingleTon single = new HungrySingleTon();
        }
    }

        只有调用getInstance()时才会加载静态内部类。无线程安全问题,也实现了懒加载。

      

      

      

      

  • 相关阅读:
    ES6 promise的用法
    elementUI el-dialog 解决embed标签无法实时更新预览PDF文件
    elementUI upload 上传 传参
    elementUI form表单验证
    Ajax 原理过程 同步与异步区别 优缺点
    《深入理解mybatis原理(十二)》 mybatis深入理解之#与$区别
    截取字符串,含有汉字和字母,不能截半个汉字
    输出一个纯英文字符串中出现次数最左的单词和次数,如果有几个次数最多的单词,全部输出
    极简主义生活方式
    MySQL中创建表指定存储引擎
  • 原文地址:https://www.cnblogs.com/lfdingye/p/7569358.html
Copyright © 2011-2022 走看看