首页 > 代码库 > 单例模式的总结

单例模式的总结

一.单例模式简介

单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):保证一个类仅有一个实例,并提供一个访问它的全局访问点。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。由于这个模式的目的是使一个类只能拥有一个实例,因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。

 

二.单例模式应用场景

对于某些场景来说,只拥有一个实例是很重要的事情,比如说系统的设置文件,一个打印机同时只能为一台机器进行服务。

 

三.实现要点

1.单例类只能拥有一个实例,即该实例应为静态的。

2.单例类必须自行创建唯一的实例,即该单例类的构造函数应为私有的。

3.单例类必须向整个体统提供唯一的实例,即该类提供了一个静态的公共方法来获取该单例类的私有对象。

 

四.三种常见的实现方式及其优缺点

1.懒汉式,优点:(1)资源利用率高;

     缺点:(1)第一次加载时不够快;(2)多线程执行时不必要的同步开销大;

2.双重锁式,优点:(1)资源利用率高;(2)去除了懒汉式中的缺点(2);

      缺点:(2)第一次加载时不够快;

3.饿汉式,优点:(1)线程安全;(2)在类加载的同时新建实例,反应速度快;

     缺点:(1)资源利用率不高;

 

五.Java代码的实现

1.懒汉式

package com.leonzou69.bean;public class SingletonPrinterOfLazy {    //声明SingletonPrinter类的一个实例    private static SingletonPrinterOfLazy instance = null;    private String tips;        //重写构造方法,使SingletonPrinter类不能被new实例化    private SingletonPrinterOfLazy() {}        //获取SingletonPrinter类实例的方法,懒汉式    public static synchronized SingletonPrinterOfLazy getInstance() {        //首先判断单例类是否被实例化        if(instance == null) {            instance = new SingletonPrinterOfLazy();        }        return instance;    }        public String getTips() {        return tips;    }    public void setTips(String tips) {        this.tips = tips;    }    }

 

 2.双重锁式

package com.leonzou69.bean;public class SingletonPrinterOfDouble {    //声明SingletonPrinter类的一个实例    private static SingletonPrinterOfDouble instance = null;        //重写构造方法,使SingletonPrinter类不能被new实例化    private SingletonPrinterOfDouble() {}        private String tips;        //获取SingletonPrinter类实例方法,双重锁式    public static SingletonPrinterOfDouble getInstance() {        //首先判断单例类是否被实例化        if(instance == null) {            synchronized (SingletonPrinterOfDouble.class) {                if(instance == null) {                    instance = new SingletonPrinterOfDouble();                }            }        }        return instance;    }        public String getTips() {        return tips;    }    public void setTips(String tips) {        this.tips = tips;    }}

3.饿汉式

package com.leonzou69.bean;public class SingletonPrinterOfHungry {    //直接初始化一个实例    private static final SingletonPrinterOfHungry instance = new SingletonPrinterOfHungry();        private String tips;        //重写默认构造函数使之不能被new关键字初始化    private SingletonPrinterOfHungry() {    }        //获取SingletonPrinterOfHungry类实例方法,饿汉式    public static SingletonPrinterOfHungry getInstance() {        return instance;            }        public String getTips() {        return tips;    }    public void setTips(String tips) {        this.tips = tips;    }}

六.测试代码以及运行结果

package com.leonzou69.main;import com.leonzou69.bean.SingletonPrinterOfDouble;import com.leonzou69.bean.SingletonPrinterOfHungry;import com.leonzou69.bean.SingletonPrinterOfLazy;public class Main {        public static void main(String[] args) {        //不能用new关键字进行实例化//        SingletonPrinterOfLazy sp = new SingletonPrinterOfLazy();//        sp.tips = "不能用new关键字进行实例化";//        System.out.println(sp.tips);                //可以使用类内部的的getInstance()方法获取SingletonPrinterOfLazy懒汉实例        SingletonPrinterOfLazy spOne = SingletonPrinterOfLazy.getInstance();        spOne.setTips("我是懒汉式单例打印机");        System.out.println(spOne.getTips());        //新建另外一个懒汉实例,获取的依然是之前的懒汉实例        SingletonPrinterOfLazy spTwo = SingletonPrinterOfLazy.getInstance();        System.out.println(spTwo.getTips());                //可以使用类内部的etInstance()方法获取SingletonPrinterOfDouble双重锁式实例        SingletonPrinterOfDouble spThree = SingletonPrinterOfDouble.getInstance();        spThree.setTips("我是双重锁式单例打印机");        System.out.println(spThree.getTips());        //新建另外一个双重锁实例,获取的依赖是之前的双重锁实例        SingletonPrinterOfDouble spFour  = SingletonPrinterOfDouble.getInstance();        System.out.println(spThree.getTips());                //可以使用类内部的etInstance()方法获取SingletonPrinterOfHungry饿汉实例        SingletonPrinterOfHungry spFive = SingletonPrinterOfHungry.getInstance();        spFive.setTips("我是饿汉式单例打印机");        System.out.println(spFive.getTips());        //新建另外一个双重锁实例,获取的依赖是之前的双重锁实例        SingletonPrinterOfHungry spSix  = SingletonPrinterOfHungry.getInstance();        System.out.println(spSix.getTips());    }}

我是懒汉式单例打印机
我是懒汉式单例打印机
我是双重锁式单例打印机
我是双重锁式单例打印机
我是饿汉式单例打印机
我是饿汉式单例打印机

七.单例模式在Android上的一个应用,点击按钮退出所有Activity。

源码地址:https://github.com/leonzou69/DesignPatterns

单例模式的总结