单例模式:

作用

保证一个类只有一个实例,并且提供一个访问该实例的全局访问入口

单例模式的常用

1.Windows的任务管理器
2.Windows的回收站,也是一个单例应用
3.项目中的读取配置文件的对象
4.数据库的连接池
5.Servlet中的Application Servlet
6.Spring中的Bean默认也是单例的
7.SpringMVC Struts中的控制器

单例模式的优点

1.由于单例模式只生成一个实例,减少了系统给的性能开销,当一个对象需要产生时,当时消耗的资源较多。那么产生对象时构建的方式就可以通过单例去构建。
2.单例模式存在全局访问点,所以可以优化共享资源访问。

常见的单例模式的构建方法:

1.饿汉式:线程安全 调用率高  但是不能延迟加载
2.懒汉式:线程安全 调用率不高 但是可以延迟加载
3.双重检测(double check )
4.静态内部类(线程安全 可以延迟加载)
5.枚举单例 线程安全 不可以延迟加载

代码案例展示

饿汉式

/**
* 饿汉式:
* 类只要被加载就会被加载全局变量,所以饿汉式,会被及时加载。(没有懒加载 )
* 并且存在天然的线程安全问题。
* @author 码歌老薛
* @date 创建时间 猴年马月
* @version 1.0
*/
public class SingleHungry {
//提供静态的全局变量 作为访问该类实例的入口
private static SingleHungry sh = new SingleHungry();
/**
* 构造器私有 无法创建对象
*/
private SingleHungry(){ }
/**
* 对外提供get方法获取 该类的实例
* @return
*/
public static SingleHungry getInstance(){
return sh;
}
}

  

 

懒汉式

/**
* 懒汉式:
* 全局变量初始化放到了实例化方法中,延迟产生对象。
* 但是当多个线程统一访问时,有可能出现线程不安全的情况。需要优化。
* @author 码歌老薛
* @date 创建时间 猴年马月
* @version 1.0
*/
public class SingleLazy implements Serializable{
//提供静态的全局变量 作为访问该类实例的入口 但是这里不立即加载
private static SingleLazy sh = null; /**
* 构造器私有 无法创建对象
*/
private SingleLazy(){
System.out.println("构造函数被调用了");
} /**
* 对外提供get方法获取 该类的实例
* @return
* @throws InterruptedException
*/
public static synchronized SingleLazy getInstance() {
if(sh==null){
sh = new SingleLazy();
}
return sh; } }
上海尚学堂java培训 shsxt.com
 

双重检测

/**
* 懒汉式:
* 全局变量初始化放到了实例化方法中,延迟产生对象。
* 但是当多个线程统一访问时,有可能出现线程不安全的情况。需要优化。
* @author 码歌老薛
* @date 创建时间 猴年马月
* @version 1.0
*/
public class SingleLazy4 {
//提供静态的全局变量 作为访问该类实例的入口 但是这里不立即加载
private volatile static SingleLazy4 sh = null; /**
* 构造器私有 无法创建对象
*/
private SingleLazy4(){
System.out.println("被调用了");
} /**
* 双重校验锁式(也有人把双重校验锁式和懒汉式归为一类)分别在代码锁前后进行判空校验
* ,双重校验锁式是线程安全的。然而,在JDK1.5以前,DCL是不稳定的,有时也可能创建多个实例,
* 在1.5以后开始提供volatile关键字修饰变量来达到稳定效果。
* 双重校验锁DCL(double checked locking)
* @return
* @throws InterruptedException
*/
public static SingleLazy4 getInstance() {
if(sh == null){
synchronized(SingleLazy4.class){
if(sh == null){
sh = new SingleLazy4();
//return singleton; //有人提议在此处进行一次返回
}
//return singleton; //也有人提议在此处进行一次返回
}
}
return sh;
}
} 上海尚学堂Java培训 shsxt.com 获取更多java学习资料
 

静态内部类

/**
*静态内部类
*
* @author 码歌老薛
* @date 创建时间 猴年马月
* @version 1.0
*/
public class SingleInner { /**
*静态内部类式和饿汉式一样,同样利用了ClassLoader的机制保证了线程安全;
*不同的是,饿汉式在Singleton类被加载时(从代码段3-2的Class.forName可见)
*就创建了一个实例对象,而静态内部类即使Singleton类被加载也不会创建单例对象,
*除非调用里面的getInstance()方法。因为当Singleton类被加载时
*,其静态内部类SingletonHolder没有被主动使用。只有当调用getInstance方法时,
*才会装载SingletonHolder类,从而实例化单例对象。 这样,通过静态内部类的方法就实现了lazy loading,很好地将懒汉式和饿汉式结合起来,
既实现延迟加载,保证系统性能,也能保证线程安全
*/
private static class SingleInnerHolder{
private static SingleInner instance = new SingleInner();
} private SingleInner(){
System.out.println("我被调用了");
}
public static SingleInner getInstance(){
return SingleInnerHolder.instance;
}
}
 

枚举单例

/**
* jvm提供底层保证
* 不可能出现序列化、反射产生对象的漏洞 但是不能做到延迟加载
在外部,可以通过EnumSingleton.INSTANCE.work()来调用work方法。默认的枚举实例的创建是线程安全的
、,但是实例内的各种方法则需要程序员来保证线程安全。
总的来说,使用枚举单例模式,有三个好处:
1.实例的创建线程安全,确保单例。2.防止被反射创建多个实例。3.没有序列化的问题。
* @author 码歌老薛
* @date 创建时间 猴年马月
* @version 1.0
*/
public enum SingleEnum {
//实例化对象
INSTANCE; /**
* 对象需要执行的功能
*/
void getInstance(){ }
} 上海尚学堂java培训 shsxt.com
 

反射/序列化 获取对象 以及防止方式

import java.io.ObjectStreamException;
import java.io.Serializable; /**
* 懒汉式:
* 全局变量初始化放到了实例化方法中,延迟产生对象。
* 但是当多个线程统一访问时,有可能出现线程不安全的情况。需要优化。
* @author 码歌老薛
* @date 创建时间 猴年马月
* @version 1.0
*/
public class SingleLazy implements Serializable{
//提供静态的全局变量 作为访问该类实例的入口 但是这里不立即加载
private static SingleLazy sh = null; /**
* 构造器私有 无法创建对象
*/
private SingleLazy(){
if(sh!=null){
throw new RuntimeException();
}
System.out.println("构造函数被调用了");
} /**
* 对外提供get方法获取 该类的实例
* @return
* @throws InterruptedException
*/
public static synchronized SingleLazy getInstance() {
if(sh==null){
sh = new SingleLazy();
}
return sh; } private Object readResolve()throws ObjectStreamException{
return sh;
} }
上海尚学堂java培训 shsxt.com
 

用法总结:

1、懒汉式效率是最低的。
2、占用资源少 不需要延时加载  枚举优于 饿汉式
3、占用资源比较多 需要延时加载 静态内部类 优于  懒汉式

更多Java技术文章欢迎阅读上海尚学堂Java培训,免费试学和线上公开课培训课程等你学习。

Java设计模式之单例模式,笔记完整到不敢想象的更多相关文章

  1. java 设计模式之单例模式

    -------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...

  2. 折腾Java设计模式之单例模式

    博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...

  3. Java设计模式之单例模式(七种写法)

    Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...

  4. Java 设计模式之单例模式(一)

    原文地址:Java 设计模式之单例模式(一) 博客地址:http://www.extlight.com 一.背景 没有太多原由,纯粹是记录和总结自己从业以来经历和学习的点点滴滴. 本篇内容为 Java ...

  5. java设计模式1——单例模式

    java设计模式1--单例模式 1.单例模式介绍 1.1.核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 1.2.常见场景 1.3.单例模式的优点 1.4.常见的五种单例模式实现 ...

  6. java设计模式之单例模式你真的会了吗?(懒汉式篇)

    java设计模式之单例模式你真的会了吗?(懒汉式篇) 一.什么是单例模式? 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供 ...

  7. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  8. java设计模式- (1)单例模式

    参加校园招聘的笔试,发现公司都会考一些java设计模式,所以上网查询相关内容,总结常用的几种单例模式. 单例模式(Singleton Pattern)是 Java中最简单的设计模式之一.这种类型的设计 ...

  9. [转]JAVA设计模式之单例模式

    原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...

  10. java设计模式之单例模式(七种方法)

    单例模式:个人认为这个是最简单的一种设计模式,而且也是在我们开发中最常用的一个设计模式. 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个 ...

随机推荐

  1. java----GUI和接口回调

    GUI: 图形用户接口 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java. ...

  2. 网络安装Centos x64 6.10

    1.下载老毛桃PE最新增强版本,然后生成一个可启动U盘. 2.在U盘或移动硬盘中创建一个目录 MYEXT,然后把centos的安装iso放到里面. 3.引导选择从外置ISO进行安装. https:// ...

  3. 【JAVA】反射总结

    反射是什么? 反射就是指程序在运行的时候可以知道一个类的自身信息. 自身信息有哪些:类方法.属性.成员变量.构造方法.包等 动态编译和静态编译  静态编译:在编译的时候进确定类型,如果绑定对象成功,n ...

  4. Docker使用docker-compose.yml构建Asp.Net Core和Mysql镜像并与Mysql数据库通信

    version: '3' services: mycore01: build: context: .   container_name: 'mycore01'   #自定义容器名 dockerfile ...

  5. java PDF分页打印

    将获取的pdf文件按页拆分:参考https://q.cnblogs.com/q/99944/ pdf文件有多页,第一页需设置横向打印,其他页设置为纵向打印. PDDocument document = ...

  6. Vue使用过程中常见问题

    目录 一.vue监听不到state数组/json对象内的元素的值的变化,要手动通知触发 二.vue用splice删除多维数组元素导致视图更新失败情况 三.vue项目如何部署到php或者java环境的服 ...

  7. react使用过程中常见问题

    目录 一.减小输入字符数 二.用props.children来引用位于前置标签和后置标签之间的内容 三.创建组件两条主要的途径 四.JSX属性采用驼峰式的大小写规则(即‘onClick’而非‘oncl ...

  8. centos6.5使用LVM

    1.添加硬盘 centos6以前的版本用kudzu来不重启识别新硬件. [root@xen01 ~]# /etc/init.d/kudzu start -bash: /etc/init.d/kudzu ...

  9. 【2019雅礼集训】【CF 960G】【第一类斯特林数】【NTT&多项式】permutation

    目录 题意 输入格式 输出格式 思路 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a, ...

  10. windows10计划任务启动bat执行jar打包的jar文件

    今天公司要用bat文件执行jar打包的java文件,运行没项目的程序,并且用任务计划开机自启,今天记录下坑 系统:win10 一.编写.bat执行用jar打包的jar文件 @echo off java ...