以下代码整理别人的,加上自己的认识,做些注释,当是笔记。
(1)第一种方式:通过final static 关键字直接让类加载时就初始化,简称恶汉式
public class SingletonClass {
private static final SingletonClass instance = new SingletonClass();
public static SingletonClass getInstance() {
return instance;
}
private SingletonClass() {
}
}
因为如上代码,类一加载就初始化了,如果类没有用到无缘消耗了资源。
所以提出延长初始化的概念(lazy loaded),即需要时再初始化。
(2)第二种方式:懒汉式,使用synchronized关键字同步方法体
public class SingletonClass {
private static SingletonClass instance = null;
public synchronized static SingletonClass getInstance() {
if (instance == null) {
instance = new SingletonClass();
}
return instance;
}
private SingletonClass() {
}
}
由于懒汉式只需第一次判断即可,如果此类需要初始化资源消耗过多时,无疑会造成性能问题,所以提出
(3)所谓的double-checked方式,懒汉式升级版
public class SingletonClass {
private static SingletonClass instance = null;
public static SingletonClass getInstance() {
if (instance == null) {//首先判断,提高性能,因为只有第一次才需要synchronized
synchronized (SingletonClass.class) {
if (instance == null) {//保证多线程条件下单例唯一
instance = new SingletonClass();
}
}
}
return instance;
}
private SingletonClass() {
}
}
但JAVA语言中却不能使用此double-checked模式,因为
语言在编译时需要编译优化,即在不改变原来语义的情况下,通过调整语句顺序,来让程序运行的更快。这个过程成为reorder。
JVM只是一个标准,并不是实现。JVM中并没有规定有关编译器优化的内容,也就是说,JVM实现可以自由的进行编译器优化。
所以,JVM就存在两种初始化对象的模型:
开辟内存空间,调用构造方法,然后指针指向内存。
开辟内存空间,指针指向内存,然后调用构造方法。
针对第二种情况,加入线程B现在调用getInstance方法,而线程A刚好在创建对象,而此时线程B判断instance不为null,事实上null还没真正初始化成功,所以出错。
(3)解决方法:
//通过volatile关键字——被volatile修饰的写变量不能和之前的读写代码调整,读变量不能和之后的读写代码调整,但需要JDK1.5以上版本支持
public class SingletonClass {
private volatile static SingletonClass instance = null;
public static SingletonClass getInstance() {
if (instance == null) {
synchronized (SingletonClass.class) {
if(instance == null) {
instance = new SingletonClass();
}
}
}
return instance;
}
private SingletonClass() {
}
}
//静态内部类处理,事实上是单例第一种方式的修改。(第一,起到了延迟初始化的作用;第二,优化了synchronized性能)
public class SingletonClass {
private static class SingletonClassInstance {
private static final SingletonClass instance = new SingletonClass();
}
public static SingletonClass getInstance() {
return SingletonClassInstance.instance;
}
private SingletonClass() {
}
}
分享到:
相关推荐
单例模式单例模式单例模式单例模式单例模式单例模式单例模式单例模式
C#单例模式C#单例模式详解C#单例模式详解C#单例模式详解
单例模式详解~~单例模式详解~~单例模式详解~~
2020-02-10 王争设计模式之美进入课程讲述:冯永吉时长 10:21大小 8.31M上两节课中,我们针对单例模式,讲解了单例的应用场景、几种常见的代码实现
首先向关注过我这个系列...这立刻让我想到了最常用也是最简单最容易理解的一个设计模式 单例模式 何为 单例模式 ? 故名思议 即 让 类 永远都只能有一个实例。 由于 示例代码 比较简单 我也加了注释,这里就不在赘述
单例模式是最简单的设计模式之一,但是对于Java的开发者来说,它却有很多缺陷。在本月的专栏中,David Geary探讨了单例模式以及在面对多线程(multithreading)、类装载器(classloaders)和序列化(serialization)时...
单例模式的七种实现方法以及分析,可以作文大作业提交 1.前言 4 1.1 课题的研究背景 4 1.2 课题主要研究目标 4 2.相关技术简介 4 2.1Java简介 4 2.2IDEA简介 4 3. 单例模式的7种实现方式 5 3.1饿汉式(使用静态常量...
一个简单的java工程,包含注释,一目了然,其中包含了单例模式的所有实现方式,懒汉式,饿汉式,双重校验,枚举,静态内部类等方式实现单例。
单例模式--只能弹出一个窗体 只能弹出一个窗体
设计模式之七种单例模式代码及ppt,包含多线程环境测试和反序列化测试
单例模式和工厂模式结合应用,实现了产品的生产,适合用做课程设计,包含详细文档和代码。Java语言。喜欢的可以下载来看看那
几种单例模式的书写方式
使用单例模式创建学生管理系统(饿汉式、懒汉式)
php单例模式php单例模式php单例模式php单例模式
模式就像是OOP开发人员的配方,每种模式都提供了所需的成分。模式对OOP开发人员尤其有用,因为它有助于创建稳定的API,...本章将介绍两种常用的模式:单例模式和工厂模式。前者被称为类的职责,后者被称为类的多态性。
这个讲的是单例模式的多种不同实现方式,希望对单例感兴趣的同学看看
是http://blog.csdn.net/lxq_xsyu/article/category/1544127博客中java设计模式的源代码。下载前请先看《设计模式——单例模式》一文。
Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式Java SE程序 单例模式...
设计模式C++学习之单例模式(Singleton)
此示例展示了Qml 的单例模式(类似全局对象,只生成一次实例,可全局使用) surfsky.cnblogs.com