Singleton——单例模式
什么是单例模式
**_确保一个类只生成一个实例,并提供一个访问它的全局访问点_**。<br />Singleton模式让类负责保存它的唯一实例,这个类可以保证没有其他实例可以被创建,并且提供一个访问该实例的方法
单例模式的角色构成
- Singleton
Singleton角色中有一个返回唯一实例的静态方法,该方法总会返回同一个实例。
示例程序
类的组成表
| 类名 | 说明 |
|---|---|
| Singleton | 只生成一个实例 |
| SingletonMain | 测试类 |
示例程序类图
Singleton类
Singleton类只会生成一个实例,Singleton类定义了一个静态成员变量singleton,在类被加载时会将singleton初始化为Singleton的实例,初始化行为仅在该类被加载时进行一次。<br />Singleton类的构造函数使用了private修饰,这是为了禁止从Singleton类外部调用构造函数。如果从Singleton类以外调用构造方法new Singleton(),会出现编译错误,getInstance()方法提供了获取Singleton类唯一实例的入口。
package com.example.singleton;public class Singleton {private static Singleton singleton = new Singleton();private Singleton() {System.out.println("生成了一个实例");}public static Singleton getInstance() {return singleton;}}
SingletonMain类
调用两次getInstance()方法获取Singleton类的实例,通过"=="判断是否为同一个实例。
package com.example.singleton;public class SingletonMain {public static void main(String[] args) {System.out.println("Start");Singleton obj1 = Singleton.getInstance();Singleton obj2 = Singleton.getInstance();if (obj1 == obj2) {System.out.println("obj1和obj2是相同的实例");} else {System.out.println("obj1和obj2是不同的实例");}System.out.println("End");}}
测试结果
Start生成了一个实例obj1和obj2是相同的实例End
拓展延伸
多线程下的单例模式
在多线程环境下,以下程序在多个线程调用getInstance()方法创建实例时,可能会生成多个实例;
示例程序:
SingletonThread类
package com.example.singleton.test;public class SingletonThread {private static SingletonThread singleton = null;private SingletonThread() {System.out.println("生成了一个实例");slowdown();}public static SingletonThread getInstance() {// 线程不安全,使用null == singleton判断实例为空后,生成了一个新的实例// 在多线程环境下,其他线程也可能判断 if (null == singleton)if (null == singleton) {singleton = new SingletonThread();}return singleton;}private void slowdown() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
SingletonThreadMain类
package com.example.singleton.test;public class SingletonThreadMain extends Thread{public static void main(String[] args) {System.out.println("Start.");new SingletonThreadMain("A").start();new SingletonThreadMain("B").start();new SingletonThreadMain("C").start();System.out.println("End.");}public void run() {SingletonThread obj = SingletonThread.getInstance();System.out.println(getName() + ": obj = " + obj);}public SingletonThreadMain(String name) {super(name);}}
测试结果
Start.End.生成了一个实例生成了一个实例生成了一个实例B: obj = com.example.singleton.test.SingletonThread@59e72e28C: obj = com.example.singleton.test.SingletonThread@4a140fe5A: obj = com.example.singleton.test.SingletonThread@2f5aff2b
