美文网首页
Java -- 单例设计模式

Java -- 单例设计模式

作者: 徘徊0_ | 来源:发表于2017-10-11 11:02 被阅读0次

    Java中单例(Singleton)模式是一种广泛使用的设计模式。单例模式的主要作用是保证在Java程序中,某个类只有一个实例存在。一些管理器和控制器常被设计成单例模式。

    1,饿汉式---在类初始化时,已经自行实例化

    public class Person{
         private static final Person person=new Person();
         //私有构造函数,外界无法使用
        private Person(){
        }
    
        //提供一个方法,获得对象
        public static Person getPerson(){
             return person;
        }
    }
    

    注:饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

    缺点:饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成,

    2,懒汉式(线程不安全)--顾名思义,什么时候用,什么时候创建

    public class Person{
        private static Person person;
        //私有构造函数
        private Person(){
        }
        public static Person getPerson(){
            if(person==null){
                person=new Person();
            }
            return person;
        }
    

    3,懒汉式(线程安全)

    public class Person{
          private static Person person=null;
          
          private Person(){
          }
          //添加 synchronized 同步锁
          public static synchronized Person getPerson(){
          if(person==null){
              person=new Person();
          }
          return person;
          }
    }
    

    注:在2.懒汉式基础上,添加同步锁,使得在多线程中可以使用。例如:当两个线程同时想创建实例,由于同一时刻只有一个线程能够得到同步锁,当第一个线程得到后第二个线程只能等待,如果没有创建该实例,就会创建。第一个线程释放同步锁以后第二个线程才能加上同步锁,执行内部代码,由于第一个线程已经创建了实例,所以第二个线程不需要重复创建。保证了多线程环境下也只有一个实例。

    缺点:每次通过 getPerson() 方法得到实例的时候都会有一个试图去获取同步锁的过程,然而加锁是很耗时的,所以能避免就避免。

    4,懒汉式(双重锁,线程安全)

    public class Person{
          private static Person person=null;
          private Person(){
          }
    
          public static Person getPerson(){
                if(person==null){
                    synchronized(Person.class){
                          if(person==null){
                                person=new Person();
                           }
                     }
                }
                return person;
          }
    }
    

    注:只有在person==null的时候,才需要获取同步锁,创建一次实例。当实例被创建,则无需试图加同步锁,避免3中的问题。

    缺点:使用双重if判断,复杂,容易出错。

    5,静态内部类(建议使用)

    public class Person{
          private Person(){
          }
          /** 
            * 静态初始化器,由JVM来保证线程安全 
            */ 
          private static class SingletonPerson{
                private final static Person person=new Person();
          }
    
          public static Person getPerson(){
                return SingletonPerson.person;
          }
    }
    

    注:上面的SingletonPerson内部类的实例与外部类的实例没有绑定关系,只有被调用才会被加载,也就是实现了延时加载。即按需创建实例。

    相关文章

      网友评论

          本文标题:Java -- 单例设计模式

          本文链接:https://www.haomeiwen.com/subject/ulgiyxtx.html