单例模式整理

敲了多年代码后,回头来看会别有一番滋味在心头。。

概念

单例模式是为了保证在一个jvm环境下,一个类仅有一个对象。

代码中常见的懒汉式。饿汉式,这些实现方式可以通过代码的设计来强制保证的单例,也可以通过文档,通过编码约束,可以认为是一个类仅有一个对象。

代码场景

项目中被封装到底层的连接功能的类,数据库连接,socket连接,具有配置功能的类,工具类,辅助系统类,会需要使用单例模式。这些类的特点:是创建和销毁需要消耗大量的系统资源,或者不需要创建多个对象。

实战

单例1,饿汉式

/**
* 最常见的单例,有两个必不可少的东西
* 1.私有化类的所有构造函数,以阻止其他代码在该类的外界去创建对象
* 2.提供获取对象的静态方法,以返回类唯一的对象引用
*
* @author sunyang
* @date 2018/11/6 18:44
*/
//单例1,通过类的静态变量来持有一个该类的对象的引用,同时使用final关键字来阻止被再次赋值
public class Singleton1 { private final static Singleton1 INSTANCE = new Singleton1(); public Singleton1() {
} public static Singleton1 getINSTANCE() {
return INSTANCE;
}
}

单例2,饿汉式

/**
* 单例2,是使用静态变量维护该类的引用,但是要将对象创建放在静态代码块中
*
* @author sunyang
* @date 2018/11/6 18:49
*/
public class Singleton2 {
private static final Singleton2 INSTANCE; static {
INSTANCE = new Singleton2();
} public Singleton2() {
} public static Singleton2 getInstance(){
return INSTANCE;
} }

单例3,懒汉式

/**
* 单例3,使用静态变量维持类的对象引用,在获取对象的方法中对象进行判断和创建
*
* @author sunyang
* @date 2018/11/6 18:59
*/
public class Singleton3 {
public static Singleton3 instance; private Singleton3(){ } private static Singleton3 getInstance(){
if (instance == null){
instance = new Singleton3();
}
return instance;
} }

分析

单例1和单例2,将对象创建放在类的初始化阶段,单例3则是将对象的创建放在类的使用阶段。

所以,单例1和单例2称为饿汉式,单例3称为懒汉式。优缺点:

饿汉式的优点是简单易懂,缺点是没有达到懒加载的效果。如果整个生命周期中自始至终未使用过这个实例,就会比较浪费连接资源和内存。

懒汉式并不复杂,可以起到懒加载的效果。于是,实际开发中更愿意使用懒汉式,因为节省内存,懒加载。

联想

类的生命周期:
1.类的加载:

将类的字节码文件.class从硬盘载入方法区的过程

2.类的连接:

该过程由三个部分组成:验证、准备和解析

3.类的初始化:

将静态变量赋值,执行的顺序就是,

父类静态变量->静态代码块->子类静态变量->子类静态代码块

饿汉式的对象创建在这个阶段

4.类的使用:

类的实例化,懒汉式的对象创建处于这个阶段,new关键字可以触发该生命周期

5.类卸载

验证

/**
* 如果验证?
* 根据类的五个生命周期阶段,我们只需要验证在创建对象之前的
* 那些操作能够触发类的初始化就行。
*
* @author sunyang
* @date 2018/11/8 11:13
*/
public class ValidSingleton1 {
/**
* 首先在构造方法里添加打印语句,打印"init"
* 再添加静态方法和一个静态变量
*
*/
private static final ValidSingleton1 INSTANCE = new ValidSingleton1(); //打印init
public ValidSingleton1() {
System.out.println("init");
} public static ValidSingleton1 getINSTANCE() {
return INSTANCE;
}
//静态方法
public static final void otherMethod(){ }
//静态变量
public static final int staticField = 0;
}

开始验证

/**
* @author sunyang
* @date 2018/11/8 11:26
*/
public class ValidSingletonDemo { public static void main(String[] args) {
System.out.println("---------------------start");
/*1.验证单例1,只声明,不会触发类的初始化阶段
ValidSingleton1 validSingleton1 = null;
if (null == validSingleton1){
System.out.println("singleton1 is null");
}*/
/*//2.调用类的静态变量
System.out.println(ValidSingleton1.staticField);*/ //3.调用类的静态方法
// ValidSingleton1.otherMethod();
//4.初始化两次
ValidSingleton1 validSingleton1 = new ValidSingleton1();
//5.直接调用
// ValidSingleton1.getINSTANCE();
System.out.println("---------------------end"); /**
* -------start-------
* singleton1 is null
* -------end---------
*
* ---------------------start
* 0
* ---------------------end
*
* ---------------------start
* init
* ---------------------end
*
* ---------------------start
* init
* init
* ---------------------end
*
*
* ---------------------start
* init
* ---------------------end
*/
}
}

从输出上看,调用类的静态方法以下,会触发类的初始化阶段。

发现饿汉式,是不会产生线程安全的问题;

在设计上,懒汉式要优于饿汉式

关联线程安全

在多线程下,懒汉式会有一定修改。当两个线程在if(null == instance)语句阻塞的时候,可能由两个线程进入创建实例,从而返回了两个对象。对此,我们可以加锁,保证仅有一个线程处于getInstance()方法中,从而保证了线程一致性。多线程下的单例

/**
* @author sunyang
* @date 2018/11/8 12:18
*/
public class Singleton4 { private static Singleton4 instance; private Singleton4(){ }
//需要加上synchronized 同步
public static synchronized Singleton4 getInstance(){
if (instance == null){
instance = new Singleton4();
}
return instance;
}
}

Java设计模式-单例模式详解(上)的更多相关文章

  1. Java设计模式 - 单例模式详解(扩展)

    单例模式引发相关整理 如何破坏单例模式 示例: /** * 如果破坏单例模式 * * @author sunyang * @date 2018/11/13 20:14 */ public class ...

  2. Java设计模式 - 单例模式详解(下)

    单例模式引发相关整理 关联线程安全 在多线程下,懒汉式会有一定修改.当两个线程在if(null == instance)语句阻塞的时候,可能由两个线程进入创建实例,从而返回了两个对象.对此,我们可以加 ...

  3. 【转】Java设计模式-单例模式详解

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6510196.html 所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该由人来控 ...

  4. java设计模式案例详解:工厂模式

    1.简单工厂模式 在不考虑扩展的情况下还是很好用的,其实我们写代码也很经常用到,其主要理解在于传入不同参数则构建不同对象,只有一个工厂,如需添加产品涉及到扩展需要修改比较多的东西,不符合开闭原则,如下 ...

  5. java设计模式案例详解:观察者模式

    观察者模式的应用场景: 1. 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变. 2. 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节. 举个例子说明,这个例子讲 ...

  6. java设计模式案例详解:代理模式

    代理模式就是用一个第三者的身份去完成工作,其实际意义跟字面意思其实是一样的,理解方式有很多,还是例子直观. 本例的实现类是实现买票功能,实际应用想要添加身份验证功能,利用代理模式添加验证步骤.上例子: ...

  7. Java设计模式----观察者模式详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  8. 9种Java单例模式详解(推荐)

    单例模式的特点 一个类只允许产生一个实例化对象. 单例类构造方法私有化,不允许外部创建对象. 单例类向外提供静态方法,调用方法返回内部创建的实例化对象.  懒汉式(线程不安全) 其主要表现在单例类在外 ...

  9. Java 反射机制详解(上)

    一.什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java ...

随机推荐

  1. mysql数据库备份_可执行文件

    这段时间接手运维的工作,刚开始就尝到了数据丢失的痛!老板抱怨,同事抱怨!都说先删库再跑路,我还不想跑! 下面是我的备份记录:(分4步) 1.编写备份执行文件sqlAutoBak.sh #!/bin/s ...

  2. java + maven 实现发送短信验证码功能

    如何使用java + maven的项目环境发送短信验证码,本文使用的是榛子云短信 的接口. 1. 安装sdk 下载地址: http://smsow.zhenzikj.com/doc/sdk.html ...

  3. 已知一个字符串S 以及长度为n的字符数组a,编写一个函数,统计a中每个字符在字符串中的出现次数

    import java.util.Scanner; /** * @author:(LiberHome) * @date:Created in 2019/3/6 21:04 * @description ...

  4. 用 Java 解密 C# 加密的数据(DES)(转)

    今天遇到java解密url的问题.我们的系统要获取外部传过来的URL,URL是采用 DES 算法对消息进行加密,再用 BASE64 编码.不过对方系统是用 C# 写的. 在网上搜了几篇文章终于找到一篇 ...

  5. 对scanf和printf的研究!!

    在做项目的时候,突然很纠结要不要清理.所以赶紧写一篇博客记一下!! 1. scanf函数 在代码中,如果碰到了两个挨着输入的情况,就会出现问题!! 输入一个字符 r 就会出现一下情况!! 第2句sca ...

  6. React Native 0.50版本新功能简介

    React Native在2017年经历了众多版本的迭代,从接触的0.29版本开始,到前不久发布的0.52版本,React Native作为目前最受欢迎的移动跨平台方案.虽然,目前存在着很多的功能和性 ...

  7. FFmpeg 结构体学习(六): AVCodecContext 分析

    在上文FFmpeg 结构体学习(五): AVCodec 分析我们学习了AVCodec结构体的相关内容.本文,我们将讲述一下AVCodecContext. AVCodecContext是包含变量较多的结 ...

  8. 为wordpress博客网站替换鼠标样式

    第一种方法是使用插件来实现这个功能,Unique Cursor  插件.可以在后台直接安装启用,然后就可以设置喜欢鼠标样式,点击保存就可以了.切记在选择的同时有二个选项一个是disable意思是关闭还 ...

  9. [Swift]LeetCode153. 寻找旋转排序数组中的最小值 | Find Minimum in Rotated Sorted Array

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  10. 机器学习 GBDT+xgboost 决策树提升

    目录 xgboost CART(Classify and Regression Tree) GBDT(Gradient Boosting Desicion Tree) GB思想(Gradient Bo ...