单例模式(Singleton Pattern) 是Java中最简单的设计模式之一,其定义如下:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。简单而言单例类只能有一个实例,这个实例是自己创建的唯一实例,然后提供全局访问的方法。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问方式。
主要解决: 一个全局使用的类频繁创建和销毁。
何时使用: 控制实例数目,节省系统资源时。
如何解决: 判断系统是否已经有这个实例,如果存在则返回,否则创建。
关键代码: 将构造函数设为私有,并提供全局方法,在此方法中对实例进行判断是创建还是直接使用。
优点: 减少内存开销,避免对资源的多重占用。
缺点: 没有接口,扩展很困难;对测试不利;与单一职责原则冲突。
应用实例: 一个班级只有一个班主任(不考虑其他外界因素)
我们创建一个ClassTeacher
类,通过定义一个私有访问权限的构造函数,防止其他类new
出来一个对象,并提供getInstance()
方法,在该方法中实例化一个自己的对象。
/**
* 班主任类
* @author 丶白小源
*
*/
public class ClassTeacher {
//创建班主任的一个私有对象
private static final ClassTeacher instance = new ClassTeacher();
//为了该类不被实例化,提供私有构造函数
private ClassTeacher(){
//不考虑外界因素,班级班主任一直不变
}
//提供全局方法
public static ClassTeacher getInstance() {
return instance;
}
//班主任讲话
public void say() {
System.out.println("今天XXX同学表现很好!");
}
}
班主任每天管理学生学习情况,对学生一周的情况进行表彰。
/**
* 学生类
* @author 丶白小源
*
*/
public class Student {
public static void main(String[] args) {
//一周五天学生见到的班主任都是同一人
for (int i = 0; i < 5; i++) {
ClassTeacher ct = ClassTeacher.getInstance();
ct.say();
}
}
}
//结果
今天XXX同学表现很好!
今天XXX同学表现很好!
今天XXX同学表现很好!
今天XXX同学表现很好!
今天XXX同学表现很好!
单例模式的几种实现方式
(1)懒汉式,线程不安全
public class ClassTeacher {
//创建班主任的一个私有对象
private static ClassTeacher instance = null;
//为了该类不被实例化,提供私有构造函数
private ClassTeacher(){
//不考虑外界因素,班级班主任一直不变
}
//提供全局方法
public static ClassTeacher getInstance() {
if(instance == null) {
instance = new ClassTeacher();
}
return instance;
}
}
(2)懒汉式,线程安全
public class ClassTeacher {
//创建班主任的一个私有对象
private static ClassTeacher instance = null;
//为了该类不被实例化,提供私有构造函数
private ClassTeacher(){
//不考虑外界因素,班级班主任一直不变
}
//提供全局方法
public static synchronized ClassTeacher getInstance() {
if(instance == null) {
instance = new ClassTeacher();
}
return instance;
}
}
(3)饿汉式,线程安全
public class ClassTeacher {
//创建班主任的一个私有对象
private static ClassTeacher instance = new ClassTeacher();
//为了该类不被实例化,提供私有构造函数
private ClassTeacher(){
//不考虑外界因素,班级班主任一直不变
}
//提供全局方法
public static synchronized ClassTeacher getInstance() {
return instance;
}
}
(4)双检锁/双重效验锁(DCL,即double-checked locking)
public class ClassTeacher {
//创建班主任的一个私有对象
private static ClassTeacher instance = null;
//为了该类不被实例化,提供私有构造函数
private ClassTeacher(){
//不考虑外界因素,班级班主任一直不变
}
//提供全局方法
public static ClassTeacher getInstance() {
if(instance == null) {
synchronized (ClassTeacher.class) {
instance = new ClassTeacher();
}
}
return instance;
}
}
(5)登记式/静态内部类
public class ClassTeacher {
private static class ClassTeacherHolder {
private static final ClassTeacher INSTANCE = new ClassTeacher();
}
//为了该类不被实例化,提供私有构造函数
private ClassTeacher(){
//不考虑外界因素,班级班主任一直不变
}
//提供全局方法
public static ClassTeacher getInstance() {
return ClassTeacherHolder.INSTANCE;
}
}
(6)枚举
public enum ClassTeacher {
INSTANCE;
public ClassTeacher getInstance() {
return INSTANCE;
}
}
编译完成后相当于:
public final class ClassTeacher extends Enum<ClassTeacher> {
public static final ClassTeacher CLASSTEACHER;
public static ClassTeacher[] values();
public static ClassTeacher valueOf(String s);
static{};
}
网友评论