zoukankan      html  css  js  c++  java
  • 单例模式一二三

    单例模式干的事情非常easy,就是要保证某一个对象全局唯一。


    对吗? 对不正确要看标准
    单例模式(Singleton Pattern):确保某一个类仅仅有一个实例,并且自行实例化并向整个系统提供这个实例。
    这个类称为单例类。它提供全局訪问的方法。单例模式是一种对象创建型模式。
    看来我之前定义的不全对。
    第一 保证类仅仅有一个实例
    第二 类本身自己实例化(意思就是不能让别的类来new自己)
    第三 提供全局訪问的方法
    OK 那我如今写出第一种Singleton

    第一种Singleton

    public class Singleton{
        private static Singleton sl;
        private Singleton(){
           System.out.println("初始化");
        }
    
        public static Singleton getInstance(){
        if(sl==null)
             sl=new Singleton();
         return sl;
        }
        
        public static void main(String[] args){
            Singleton sl=Singleton.getInstance();
            Singleton sl2=Singleton.getInstance();
        }
    }
    执行结果是显示一个初始化
    可是这里存在一个问题 假设多个线程同一时候执行这段代码,当第一个线程执行到sl=new Singleton()时(这一句还没有执行),第二个线程检查sl还是为null的,此时第二个线程也进来了... 然后就有多个对象了。

    所以有

    另外一种Singleton

    /***
     * 饿汉模式
     */
    public class Singleton2{
        private final static Singleton2  sl2=new Singleton2();
        private Singleton2(){
            System.out.println("初始化");
        }
        public static Singleton2 getInstance(){
            return sl2;
        }
        public static void main(String[] args){
            Singleton2 sl2=Singleton2.getInstance();
            Singleton2 sl3=Singleton2.getInstance();
        }
    }
    这样的单例模式,我们在类载入的时候,就把类变量new出来。这样的方式我们称之为饿汉模式。
    首先饿汉问题攻克了上面的线程问题。我最開始载入的时候就有了类变量了而且还仅仅有一个,自然不会存在线程问题了。
    但这里有个性能问题,无论我用不用这个单例类,它总会被载入内存中,因此性能是个问题。


    上面说了这个模式叫饿汉模式,那自然有非饿汉模式(术语叫懒汉模式)。只是在这里我不太想和大家聊懒汉模式,太复杂,且不怎么用。
    那有没有一种单例,既能解决第一个的线程问题,同一时候保持性能(事实上另外一种饿汉模式就不错了,就那一个类,能拖多少性能?就算有10个,100个也不是太多)呢?并且也不像我说的那个"懒汉模式"那么复杂呢?


    答案是肯定的。

    有!

    内部类模式

    public class Singleton3{
        private static class hold{
            private  final static Singleton3 sl3=new Singleton3();
        }
        private Singleton3(){
        System.out.println("初始化");
        }
        public static Singleton3 getInstance(){
              return hold.sl3;
        }
        public static void main(String[] args){
                 Singleton3 sl3=Singleton3.getInstance();
             Singleton3 sl4=Singleton3.getInstance();
             System.out.println(sl3==sl4);
        }
    }
    关于内部类与static,final的分析,我们这里临时不讲。
    内部类的方式攻克了上面所提的几个问题。


    但也引出了一个不是问题的问题

    内部类是java支持的,可是在别的语言中,不一定。

    參考资料

    http://blog.csdn.net/lovelion/article/details/7420883
  • 相关阅读:
    c# 根据当前时间获取,本周,本月,本季度,月初,月末,各个时间段
    Button 对 TreeView1 所有节点的全选
    启动Myeclipse报错“Failed to create the Java Virtual Machine”的解决办法
    Myeclipse 启动报错 Failed to create the java Virtual Machine
    ng-cordova和cordova区别
    Java高效计数器
    WebView 简介
    Hibernate——(4)Hibernate映射类型
    Hibernate——(3)主键生成方式
    Hibernate——(2)增删改查
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6985436.html
Copyright © 2011-2022 走看看