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

    单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    通常我们可以定义一个全局变量使得一个对象被访问,但它不能阻止我们实例化多个对象,所以一个最好的办法就是让类自身保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且提供一个访问该实例的方法。

    public class Singleton {
        private static Singleton instance;
        private Singleton(){
            
        }
        public static Singleton getInstance(){
            if(instance == null){
                instance = new Singleton();
            }
            return instance;
        }
    }
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Singleton s1 = Singleton.getInstance();
            Singleton s2 = Singleton.getInstance();
            if(s1 == s2){
                System.out.println("两个对象是相同的实例");
            }
        }
    
    }

    这里特别要注意singleton类的构造方法是私有的,这样可以防止通过new的方式创建该对象,而只能通过getInstance方法获得。我们还有些细节需注意,在多线程程序中,如果多个线程同时访问singleton类,并调用getInstance方法,会有可能创建多个对象。这时可以给进程一把锁来处理。

    public class Singleton1 {
        private static Singleton1 instance;
        private static final Object syncRoot = new Object();
        private Singleton1(){
            
        }
        public static Singleton1 getInstance(){
            synchronized (syncRoot) {
                if(instance == null){
                    instance = new Singleton1();
                }
            }
            return instance;
        }
    }

    这段代码使得对象由最先进入的那个线程创建,以后线程在进入时不会再去创建对象实例。由于有了lock,保证了在多线程情况下不会创建多个对象。但这个写法在每次调用getInstance方法时都要获取锁,影响程序性能,所以这个类还得改良。

    public class Singleton2 {
        private static Singleton2 instance;
        private static final Object syncRoot = new Object();
        private Singleton2(){
            
        }
        public static Singleton2 getInstance(){
            //先判断实例是否存在,不存在再加锁处理,此做法被称为Double-Check Locking(双重锁定)
            if(instance == null){
                synchronized (syncRoot) {
                    if(instance == null){
                        instance = new Singleton2();
                    }
                }
            }
            return instance;
        }
    }

    实例在未被创建时再加锁处理,保证了多线程的安全,这种做法被称为Double-Checking Locking 双重锁定。

    除了上面几种懒汉式单例类,还有一种饿汉式单例,这种静态初始化方式是在自己被加载时就将自己实例化。所以会提前占用系统资源。

    饿汉式单例类:

    public class Singleton3 {
        private static final Singleton3 instance = new Singleton3();
        private Singleton3(){
            
        }
        public Singleton3(String name){
            
        }
        public static Singleton3 getInstance(){
            return instance;
        }
    }

    需要注意的是instance的修饰为static final。

  • 相关阅读:
    Java Servlet(四):Servlet接口service工作(ServletRequest,ServletResponse对象)(jdk7+tomcat7+eclipse)
    Eclipse 创建文件快捷菜单、避免格式化时自动换行、.properties文件中文乱码、在线安装FreeMarker
    Java Servlet(三):Servlet中ServletConfig对象和ServletContext对象
    Java Servlet(二):servlet配置及生命周期相关(jdk7+tomcat7+eclipse)
    Java Servlet(一):创建工程(jdk7+tomcat7+eclipse)
    FlashFXP5_gr坑爹的故事
    数据库备份,及清理备份计划
    Could not load file or assembly'System.Data.SQLite.dll' or one of its depedencies
    ASP.NET MVC中,怎么使用jquery/ajaxForm上传文件
    Bootstrap modal被sliverlight掩盖。
  • 原文地址:https://www.cnblogs.com/shicaiyou/p/9356027.html
Copyright © 2011-2022 走看看