网站首页 > 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日
猜你喜欢
- 2024-09-22 带你了解单例模式(Singleton Pattern)的五种写法!
- 2024-09-22 单例模式的常用写法(单例模式三种写法)
- 2024-09-22 GoF之单例模式详解(单例模式在哪里使用)
- 2024-09-22 设计模式之-单例模式(单例设计模式的作用)
- 2024-09-22 Java(面试)——单例模式(java中单例模式的实现)
- 2024-09-22 在Java中实现单例模式(java单例模式实现方式)
- 2024-09-22 Java单例模式(java单例模式双重检查)
- 2024-09-22 本文将给大家介绍java中设计模式——单例模式
- 2024-09-22 java面试:单例模式,一篇就够了(java单例模式写法)
- 2024-09-22 Java设计模式(十八):单例模式(java的单例设计模式)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)