### 1. 概述
> 单例模式是确保某一个类中有且只有一个实例。

----------
### 2. 饿汉式单例
``` java
public class SingletonInstance {
private static SingletonInstance mInstance = new SingletonInstance();
// 默认私有构造方法
private SingletonInstance(){}
// 静态工厂方法
public static SingletonInstance getInstance(){
return mInstance ;
}
}
```
在饿汉式单例中,静态变量会在私有构造方法中初始化,这时候唯一的实例就被创建出来了,饿汉式主要使用到的是**空间换时间**的思想,在类还在加载的时候,对象实例便已经创建好了。

----------

### 3. 懒汉式单例
```java
public class SingletonInstance {
private static SingletonInstance mInstance = null;
// 私有默认构造方法
private SingletonInstance(){}
// 静态工厂方法
public static synchronized SingletonInstance getInstance(){
if(mInstance == null){
mInstance = new SingletonInstance();
}
return mInstance;
}
}
```
对于懒汉式单例的处理,使用了``synchronized``参数修饰工厂方法,用来在多线程环境中解决同步问题,懒汉式主要是使用到的是**时间换空间**的思想,在获取实例的时候进行判断,只有在需要的时候才去创建对象,节省内存空间,但是缺点就是实现的方式是线程安全的,这样会降低访问的速度。

----------
### 4. 双重加锁单例
```java
public class SingletonInstance {
private volatile static SingletonInstance mInstance = null;
private SingletonInstance(){}
public static SingletonInstance getInstance(){
//先检查实例是否存在,如果不存在才进入下面的同步块
if(mInstance == null){
//同步块,线程安全的创建实例
synchronized (SingletonInstance .class) {
//再次检查实例是否存在,如果不存在才真正的创建实例
if(mInstance == null){
mInstance = new SingletonInstance ();
}
}
}
return mInstance;
}
}
```
双重加锁机制指的是,在每次进入``getInstance``方法先不同步,而是进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块,这属于第一重检查,进入同步块过后再检查实例是否存在,如果不存在,就在同步的情况下创建一个新的实例,这属于第二重检查。这样便只需要同步一次,并减少了在多次同步情况下进行判断浪费的时间。
这种实现方式会使用到**volatile**关键字,意思是被**volatile**修饰的变量的值,不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而保证线程正确的处理该变量。
> **volatile**关键字在**JDK5**之前的版本中加锁失败,注意之。而且**volatile**关键字会屏蔽掉虚拟机中的一些必要的代码优化,因此虽然能实现双重检查加锁机制的单例,但并不建议大量采用。

那有什么方案可以既能达到延迟加载,又能实现线程安全的目的呢?

-----
### 5. Lazy Initialization Holder Class模式
```java
public class SingletonInstance {

private SingletonInstance(){}
/**
* 类级的内部类的实例与外部类的实例没有绑定关系,而且只有被调用到时才会装载
*/
private static class SingletonHolder{
/**
* 静态初始化,由JVM来保证线程安全
*/
private static SingletonInstance mInstance = new SingletonInstance();
}
public static SingletonInstance getInstance(){
return SingletonHolder.mInstance;
}
}
```
如果只是想简单的实现线程安全的单例,可以使用之前的**饿汉式**方式。但是缺点就是会在类装载的时候初始化对象,造成空间的浪费。
那么只要解决了类加载时自动初始化对象的问题,便可以解决问题。因此可以采用类级内部类的方式去实现,这样的话,只有在需要的时候才会创建对象实例,也达到了延迟加载和线程安全的目的。
从实现过程来看,但调用`getInstance`方法时,它会读取`SingletonHolder.mInstance`,从而初始化,在这个类被装载的时候,也会初始化静态成员,而由于静态域的特性,只会初始化一次,并且由JVM来保证线程安全。
>- 什么是类级内部类?
被`static`修饰的成员内部类才是类级内部类,如果没有被`static`修饰则被称为对象内部类,而且类级内部类与外部类对象不存在依赖关系,只有在第一次使用的时候才会被调用。
>- 多线程默认同步锁知识?
在多线程开发中,我们主要使用`synchronized`来对互斥锁进行同步控制,但是某些情况下JVM已经为我们进行了同步控制了,主要有:
1. 静态初始化方法初始化数据时;
2. 访问`final`字段时;
3. 在创建线程之前创建对象时;
4. 线程可以看见要处理的对象时;

----------
### 6. 枚举式单例
```java
public enum SingletonInstace{
// 定义一个枚举元素,它代表了一个实例
mInstance;
// 单例的操作
public void singletonOperation(){

}
}
```
使用枚举的方式既使得代码简洁,而且也由JVM来保证序列化机制,防止多次实例化,是最佳的实现单例的方式。

【Java设计模式】单例模式的更多相关文章

  1. java设计模式单例模式 ----懒汉式与饿汉式的区别

    常用的五种单例模式实现方式 ——主要: 1.饿汉式(线程安全,调用率高,但是,不能延迟加载.) 2.懒汉式(线程安全,调用效率不高,可以延时加载.) ——其他: 1.双重检测锁式(由于JVM底层内部模 ...

  2. Java设计模式の单例模式

    -------------------------------------------------- 目录 1.定义 2.常见的集中单例实现 a.饿汉式,线程安全 但效率比较低 b.单例模式的实现:饱 ...

  3. JAVA设计模式-单例模式(Singleton)线程安全与效率

    一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...

  4. Java设计模式 - - 单例模式 装饰者模式

    Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...

  5. 【设计模式】Java设计模式 - 单例模式

    [设计模式]Java设计模式 - 单例模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 分享学习心得,欢迎指正,大家一起学习成长! 原创作品,更多关注我CSDN: ...

  6. Java 设计模式 —— 单例模式

    1. 概念: 单例模式是一种常用的软件设计模式.核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果 ...

  7. Java设计模式 - 单例模式 (懒汉方式和饿汉方式)

    概念: Java中单例模式是一种常见的设计模式,单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的写法有好几种,这 ...

  8. java设计模式——单例模式(一)

    一. 定义与类型 定义:保证一个类仅有一个实例,并提供一个全局访问点 类型:创建型 二. 适用场景 想确保任何情况下都绝对只用一个实例 三. 优缺点 优点: 在内存里只有一个实例,减少了内存开销 可以 ...

  9. JAVA设计模式--单例模式

    单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 核心知识点如下: (1) 将采用单例 ...

  10. Java设计模式-单例模式(Singleton)

    单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处: 1.某些类创建比较频繁,对于一些大型的对象,这是一笔 ...

随机推荐

  1. android-sdks/build-tools/17.0.0/aapt: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory

    fedora 23:dnf install zlib.i686 libstdc++.i686

  2. Java程序员的日常—— 《编程思想》关于类的使用常识

    Java虽然利用JVM,让程序员可以放心大胆的使用,可是仍然会出现内存泄露等问题.世上没有绝对的银弹,因此也不能完全把所有的任务都交给JVM,了解Java中的初始化与垃圾回收还是必不可少的知识. 关于 ...

  3. 使用paramikoHelper类实现MySQL安装和数据恢复

    本脚本实现远程Linux主机登陆和安装MySQL的rpm包,同时导入mysql数据,实现自动化安装 paramikoHelper类在本博客中 http://www.cnblogs.com/djoker ...

  4. django with mysql (part-2)

    step01: write a ( views.py ) file vim views.py Insert the below code : step02: configure your ( urls ...

  5. asp.net时间 日期(DateTime) 的格式处理

    日期格式化{0:yyyy-MM-dd HH:mm:ss.fff}与{0:yyyy-MM-dd hh:mm:ss.fff}的区别 使用24小时制格式化日期:{0:yyyy-MM-dd HH:mm:ss. ...

  6. [原创]Java性能优化权威指南读书思维导图

    [原创]Java性能优化权威指南读书思维导图 书名:Java性能优化权威指南 原书名:Java performance 作者: (美)Charlie Hunt    Binu John 译者: 柳飞 ...

  7. RabbitMQ 入门

    简介   RabbitMQ是一个Message Broker,核心思想就是接受消息,转发消息. 实现的协议:AMQP.   术语(Jargon)   P,Producing,制造和发送信息的一方. Q ...

  8. Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)

    一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)篇 二.本篇目标: l  说说关于cocos2dx手机分辨率适配 l  对前一篇完成的塔防游戏原型进 ...

  9. 源代码安装 MySQL 5.6.28

    本文内容 创建 MySQL 用户和组 解压 MySQL 源代码包 生成配置安装文件 编译和安装 MySQL 配置文件 创建 MySQL 授权表 MySQL 目录授权 启动 MySQL 验证 MySQL ...

  10. React直出实现与原理

    前一篇文章我们介绍了虚拟DOM的实现与原理,这篇文章我们来讲讲React的直出. 比起MVVM,React比较容易实现直出,那么React的直出是如何实现,有什么值得我们学习的呢? 为什么MVVM不能 ...