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

    单例模式的作用是保证整个程序在一次运行的中,这个类的对象有且只有一个,在struts1中的action就是单例模式,但到了struts2就变成了,action对象为每个请求产生一个实例。本文将描述几种单例模式实现的方案

    从分类上来讲,可以分为饿汉式单例模式和懒汉式单例模式

      懒汉式单例模式:在类加载时不初始化

      饿汉式单例模式:在类加载时就完成初始化,因此类加载的速度会比较慢,但获取对象快

    基本实现思路

      1、构造方法私有,没法从外部直接new对象

      2、对外部提供获取该类的实例的静态方法

      3、在类的内部创建对象,通过2的方法返回

    1、饿汉式(没有实现延迟加载)

     1 public class SimpleSingleton {
     2   //唯一实例
     3   private static SimpleSingleton  instance = new SimpleSingleton ();
     4   // 返回唯一实例
     5   public static SimpleSingleton getInstance(){
     6     return instance;
     7   }
     8   //构造方法私有
     9   private SimpleSingleton (){}
    10 }

    这种方法有一个缺点,在虚拟机加载类的时候,会在初始化阶段就为静态变量赋值,没有实现延迟加载(尽可能晚的实例化对象,避免在类加载的过程中让虚拟机去创建这个对象)

    2、饿汉式

    public class SimpleSingleton {
       //唯一实例
       private static SimpleSingleton  instance = null;
       static{
        instance = new SimpleSingleton();
      }
      private static SimpleSingleton getInstance(){
        return instance;
      }
      //构造方法私有
      private SimpleSingleton (){}
    }

    看起来差别挺大的,但是和1差不多,都是在类初始化的时候实例化instance

    3、静态内部类(推荐)

    public class Singleton {
        private static class SingletonHolder{
            private static final Singleton instance = new Singleton();
        }
        private Singleton(){}
        public static final Singleton getInsatance(){
            return SingletonHolder.instance;
        }
    }

    这一种方式,比1、2更加合理,使用了静态内部类,在外部类被加载的时候,instance不一定会被初始化,因为内部类没有被主动的使用,

    4、懒汉式(线程不安全)

    public class Singleton {
        private static Singleton instance;
        private Singleton(){}
        public static Singleton getInstance(){
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    延迟加载,并且多线程出问题

    5、懒汉式(线程安全)

    public class Singleton {
        private static Singleton instance;
        private Singleton(){}
        public static synchronized Singleton getInstance(){
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    对方法加了锁,多线程能很好工作,也实现了延迟加载,但是效率很低,很多情况下也不需要同步

    6、懒汉式(同步代码块)

    public class Singleton {
    
        private static Singleton singleton;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    singleton = new Singleton();
                }
            }
            return singleton;
        }
    }

    因为5的效率太低了,所以使用同步代码块的方法,但是这样真的起作用了吗?线程1通过If判断,此时线程2也通过if判断,还是会产生多个实例

    7、双重检验锁(推荐)

    public class Singleton {
    
        private static volatile Singleton singleton;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }

    为了防止6的问题,那么判断2次就好了,实例化代码只执行一次

    8、枚举(推荐)

    public enum Singleton {
        INSTANCE;
        public void whateverMethod() {}
    }

    JDK1.5之后添加的,能避免多线程的同步问题,还能防止反序列化重新创建新的对象

  • 相关阅读:
    [转]Ctags 使用细节
    [转]ctags的使用及相关参数介绍
    [转]ubuntu面板 图标缺失的处理办法
    压缩空气动力自行车
    丰富的开发体验和激动人心的用户体验:XAML
    发现一个控件,介绍一下
    智能电视的设想(发明畅想)
    裹脚布
    整理了《类库开发的设计准则》一文
    关于设计器类程序的模型,先记录下来,怕以后忘记了
  • 原文地址:https://www.cnblogs.com/ccxka/p/9596830.html
Copyright © 2011-2022 走看看