一.单例模式简介
单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 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
时间: 2024-09-30 15:06:00