定义:保证一个类有且仅有一个实例,并且自行实例化(无需手动new)向整个系统提供。
通过单例模式可以保证系统内只会存在该类的一个实例,从而方便了对实例数量的控制和系统资源的节约。如果希望在系统中,某个类的实例只存在一个,那单例模式是最好的解决方案。所谓一山不能容二虎,一夫不能有二妻,就是这个道理。
单例模式要素:
1.私有构造方法
2.私有静态引用指向自己实例
3.以自己实例为返回值的公有静态方法
使用场景:
1.要求生成唯一序列号的环境
2.在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的
3.创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源
4.需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当然,也可以直接声明为static的方式)
5.配合配置信息进行使用,例如将配置信息放入一个properties文件中,利用一个单例可以获取该文件中的各项配置内容
单例模式又称为单子模式或singleton模式。singleton模式又分为两种:懒汉式和饿汉式。
懒汉式
/**
* 单例模式-懒汉式
*
* @auth zhangjingxuan
* @since 2018年4月11日上午9:47:50
*/
public class Singleton2 {
//1.创建类的唯一实例,使用private static修饰
private static Singleton2 instance;
//2.将构造方式私有化,不允许外边直接创建对象
private Singleton2() {
System.out.println("Singleton2初始化完毕");
}
//3.提供一个用于获取实例的方法,使用public static修饰
public static Singleton2 getInstance(){
if(instance==null){
instance=new Singleton2();
}
return instance;
}
//4.其他方法尽可能使用static进行修饰
public static void doSomething() {
System.out.println("Singleton2 doSomething");
}
}
饿汉式
/**
* 单例模式-饿汉式
*
* @auth zhangjingxuan
* @since 2018年4月11日上午9:45:30
*/
public class Singleton1 {
//1.创建类的唯一实例,使用private static修饰
private static Singleton1 instance = new Singleton1();
//2.将构造方式私有化,不允许外边直接创建对象
private Singleton1() {
System.out.println("Singleton1初始化完毕");
}
//3.提供一个用于获取实例的方法,使用public static修饰
public static Singleton1 getInstance(){
return instance;
}
//4.其他方法尽可能使用static进行修饰
public static void doSomething() {
System.out.println("Singleton1 doSomething");
}
}
测试
public class Test {
public static void main(String[] args) {
Singleton1.doSomething();
Singleton2.doSomething();
}
}
结果
Singleton1初始化完毕
Singleton1 doSomething
Singleton2 doSomething
懒汉式vs饿汉式:
1.在编码上主要区别是上述代码的第一步,是否需要在getInstance()之前进行实例化
2.懒汉式的特点是加载类的时候比较快,但运行时获取实例时比较慢,线程不安全
3.饿汉式的特点是加载类的时候比较慢(需要实例化),但运行时获取实例(getInstance())时比较快,线程安全
4.当懒汉式不获取实例而直接调用doSomething时,不会实例化操作
5.当饿汉式不获取实例而直接调用doSomething时,依然进行实例化操作
综上可知,懒汉模式是线程安全的,但在某些场景下会浪费系统资源。饿汉模式是线程不安全的,但相对懒汉模式会节约系统资源。所以,如果能有一种包含单例特点、线程安全和节约系统资源三种特点为一身的写法该有多好!程序界有一句话是“只要你能想到,我们就能给你做到”,因此这种奢华的写法也出现了。
线程安全&节约资源的单例模式(懒汉式+线程锁)
/**
* 单例模式-懒汉式
*
* @auth zhangjingxuan
* @since 2018年4月11日上午9:47:50
*/
public class Singleton3 {
//1.防止利用反射调用单例,从而破坏单例模式的flag(在构造函数中会用到)
private static boolean initialized = false;
//2.静态的内部类(寄生虫),解决多线程安全问题
private static class LazyHolder {
private static final Singleton3 instance = new Singleton3();
}
//3.构造函数(配合initialized使用)
private Singleton3() {
//解决反射破坏到单例
synchronized (Singleton3.class) {
if (!initialized) {
initialized = true;
System.out.println("Singleton3初始化完毕");
} else {
throw new RuntimeException("禁止初始化...");
}
}
}
//4.提供一个用于获取实例的方法,使用public static修饰
public static Singleton3 getInstance() {
return LazyHolder.instance;
}
public static void doSomething() {
System.out.println("Singleton3 doSomething");
}
}
感谢以下博客达人,摘要文献来自以下:
相关推荐
创建对象的模式(使用范围):scope控制,可以使用singleton和prototype d.初始化:<bean init-method=""/> e.资源释放:<bean destroy-method=""/>仅对单例对象有效 (2)IoC概念 Inversion of Control 控制反转...
在C中,可以利用静态变量来实现单例模式。静态变量具有程序生命周期内的唯一性和持久性,非常适合用于单例模式。例如: ```c typedef struct { int data; } Singleton; static Singleton* singleton_instance = ...
C中实现单例模式7.4 子类化Singleton7.5 线程安全7.6 在Cocoa Touch框架中使用单例模式7.6.1 使用UIApplication类7.6.2 使用UIAccelerometer类7.6.3 使用NSFileManager类7.7 总结第三部分 接口适配第8章 适配器8.1 ...
实现Singleton模式的关键在于确保在多线程环境下也能正确地创建单例对象。 ##### 1.4 Builder模式 Builder模式将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式特别适用于构建...
##### 1.1 Factory模式 Factory模式定义了一个创建对象的接口,但允许子类决定实例化哪一个类。Factory模式让类的实例化推迟到子类。 **应用场景**: 当需要创建的对象类型不确定或者需要通过配置文件来决定具体...
- **代码实现**:通过私有构造函数和静态成员函数来实现单例模式。 **1.4 Builder模式** - **定义**:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。 - **适用场景**:当创建复杂对象...
单例模式确保一个类只有一个实例,并提供一个全局访问点。在C++中,可以通过私有构造函数和静态成员函数来实现,防止外部实例化,并通过静态成员函数提供全局访问。 #### 1.4 Builder模式 构建者模式将一个复杂...
- **设计模式**: Java程序员广泛采用设计模式来解决常见问题,如单例模式(Singleton)、工厂模式(Factory)等。 - **代码质量**: 强调代码的可读性、可维护性和可扩展性,提倡编写干净简洁的代码。 #### 结论 Java...
例如,单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点;工厂模式(Factory Pattern)定义了一个创建对象的接口,但让子类决定实例化哪一个类。此外,结构设计也非常关键,合理的数据...
Spring 只解决了单例模式下的属性循环依赖问题(非构造函数循环依赖)。解决方式为: - 在创建 Bean 时,首先通过无参构造器创建出一个 `exposedObject` 并将其放置在一个缓存 Map 中(提前暴露引用)。 - 在属性...
- **Singleton**:单例模式保证一个类只有一个实例,并提供一个全局访问点。 - **Command**:命令模式将请求封装为对象,以便使用不同的请求、队列请求或记录请求日志。 - **Factory**:工厂模式提供创建对象的接口...
例如,在单例模式的实现中,通常采用双重检查锁定(Double-Checked Locking, DCL)模式,但如果不恰当地使用`volatile`关键字,可能会导致线程安全问题。具体来说,如果`Singleton`对象在尚未完全构造完成时被另一个...
- **Singleton:** 用于创建单例对象。 **8.4 Require, load和include** - **require/load:** 用于加载外部的Ruby文件。 - **include:** 用于将一个模块混合到当前类中。 #### 九、异常 **9.1 异常处理** ...
综上所述,“认我测”在线认证检测系统,率先填补了认证检测领域移动端的空缺,提供了Web浏览器+移动端的双端访问模式,给用户提供了多种访问途径,真正实现了用户和检测机构的随时随地在线下单检测。 关键词:...