专业编程基础技术教程

网站首页 > 基础教程 正文

Java设计模式之单例模式解析

ccvgpt 2024-08-05 12:28:21 基础教程 28 ℃

单例模式有几种经典的用法,如懒汉,恶汉,双重校验锁,枚举和静态内部类。下面为大家分别介绍一下。如不清楚的或有疑问的,请留言回复。感觉不错的,欢迎各位关注技术布道者头条号,不断为大家分享干货。

Java设计模式之单例模式解析

Java设计模式之单例模式UML示例图

1、懒汉式单例模式

public class Singleton {

private static Singleton instance = null;

private Singleton (){}

public static synchronized Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

这种写法能够在多线程中很好的工作,而且也确实在初次使用时才初始化,但是,每次实例化singleton实例的时候都有一个试图去获取同步锁的过程。

加锁太耗时,不是最佳方式,尽量避免。

2、双重校验锁式单例模式

public class Singleton {

private volatile static Singleton singleton;

private Singleton (){}

public static Singleton getSingleton() {

if (singleton == null) {

synchronized (Singleton.class) {

if (singleton == null) {

singleton = new Singleton();

}

}

}

return singleton;

}

}

这个是懒汉式单例模式的升级优化,只有当instance为null时,需要获取同步锁,创建一次实例。当实例被创建,则无需试图加锁。

但在jdk的里程碑版本1.5之后就变得很有意义 而且现在以及被广泛使用 因为引入了修饰符volatile。这也是为什么说jdk1.5才能使用双重校验

3、饿汉式单例模式

public class Singleton {

private static final Singleton instance = new Singleton();

private Singleton (){}

public static Singleton getInstance() {

return instance;

}

}

这种方式基于classloder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。

声明的final修饰符保证instance不会被其他程序所修改。

4、静态内部类式单例模式

public class Singleton {

private static class SingletonHolder {

private static final Singleton INSTANCE = new Singleton();

}

private Singleton (){}

public static final Singleton getInstance() {

return SingletonHolder.INSTANCE;

}

}

定义一个私有的内部类,在第一次用这个嵌套类时,会创建一个实例。而类型为SingletonHolder的类,只有在Singleton.getInstance()中调用,由于私有的属性,他人无法使用SingleHolder,不调用Singleton.getInstance()就不会创建实例。这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,这种方式即可以实现懒加载,又可以保证线程安全,是个人推荐的单例使用方式。

它跟恶汉式单例模式不同的是:恶汉式单例模式是只要Singleton类被装载了,那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。而且Singleton的实例化在加载SingletonHolder类时进行初始化instance。

5、枚举式单例模式

public enum Singleton {

INSTANCE;

public void whateverMethod() {

}

}

这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。但实际工作中很少见到这种使用方式。


Java设计模式

感觉有帮助的,欢迎关注、转发、收藏,楼下点赞,大家的鼓励是我们前进的动力;有不清楚或疑问的,请留言,大家一起交流。

本文由“技术布道者”发布,2017年04月24日

最近发表
标签列表