1. 什么是单例模式

单例模式指的是在应用整个生命周期内只能存在一个实例。单例模式是一种被广泛使用的设计模式。他有很多好处,能够避免实例对象的重复创建,减少创建实例的系统开销,节省内存。

2单例模式的实现

1、一个私有的构造方法

2、一个私有的静态的当前类的对象作为属性

3、一个公共的静态的返回对象的方法

3. 单例模式和静态类的区别

首先理解一下什么是静态类,静态类就是一个**类里面都是静态方法和静态field**,**构造器被private修饰**,因此不能被实例化。Math类就是一个静态类。 知道了什么是静态类后,来说一下他们两者之间的区别:



知道了什么是静态类后,来说一下他们两者之间的区别: 1)首先单例模式会提供给你一个全局唯一的对象,静态类只是提供给你很多静态方法,这些方法不用创建对象,通过类就可以直接调用; 2)单例模式的灵活性更高,方法可以被override,因为静态类都是静态方法,所以不能被override;

3)如果是一个非常重的对象,单例模式可以懒加载,静态类就无法做到;

那么时候时候应该用静态类,什么时候应该用单例模式呢?首先如果你只是想使用一些工具方法,那么最好用静态类,静态类比单例类更快,因为静态的绑定是在编译期进行的。如果你要维护状态信息,或者访问资源时,应该选用单例模式。还可以这样说,当你需要面向对象的能力时(比如继承、多态)时,选用单例类,当你仅仅是提供一些方法时选用静态类。

3.如何实现单例模式

1. 饿汉模式(线程安全)

所谓饿汉模式就是立即加载,一般情况下再调用getInstancef方法之前就已经产生了实例,也就是在类加载的时候已经产生了。这种模式的缺点很明显,就是占用资源,当单例类很大的时候,其实我们是想使用的时候再产生实例。因此这种方式适合占用资源少,在初始化的时候就会被用到的。

class SingletonHungary {
        private static SingletonHungary singletonHungary = new SingletonHungary();
        //将构造器设置为private禁止通过new进行实例化
        private SingletonHungary() {
    
        }
        public static SingletonHungary getInstance() {
            return singletonHungary;
        }
    }
2. 懒汉模式(非线程安全和synchronized关键字线程安全版本 )

懒汉模式就是延迟加载,也叫懒加载。在程序需要用到的时候再创建实例,这样保证了内存不会被浪费。针对懒汉模式

class SingletonLazy1 {
        private static SingletonLazy1 singletonLazy;
        private SingletonLazy1() {
        }
        public static SingletonLazy1 getInstance() {
            if ( singletonLazy==null) {
                singletonLazy = new SingletonLazy1();
            }
            return singletonLazy;
        }
    }

所谓 “ 懒汉式” 就是说单例实例在第一次被使用时构建,而不是在JVM在加载这个类时就马上创建此唯一的单例实例。

但是上面这种方式很明显是线程不安全的,如果多个线程同时访问getInstance()方法时就会出现问题。如果想要保证线程安全,一种比较常见的方式就是在getInstance() 方法前加上synchronized关键字,如下:

public static synchronized SingletonLazy1 getInstance() {  
    	      if (singletonLazy== null) {  
    	          singletonLazy= new SingletonLazy1();  
    	      }  
    	      return singletonLazy;  
          }
懒汉式(双重检查加锁版本)
public class SingletonLazy1 {
    
        //volatile保证,当singletonLazy变量被初始化成Singleton实例时,多个线程可以正确处理singletonLazy变量
        private volatile static SingletonLazy1 singletonLazy;
        private SingletonLazy1 () {
        }
        public static SingletonLazy1 getInstance() {
           //检查实例,如果不存在,就进入同步代码块
            if (singletonLazy== null) {
                //只有第一次才彻底执行这里的代码
                synchronized(SingletonLazy1 .class) {
                   //进入同步代码块后,再检查一次,如果仍是null,才创建实例
                    if (singletonLazy== null) {
                        singletonLazy= new SingletonLazy1 ();
                    }
                }
            }
            return singletonLazy;
        }
    }