预加载模式

代码:

public class Singleton
{
    private volatile static Singleton singleton = new Singleton();
    private Singleton()  {    }
    public static Singleton getInstance()   {
        return singleton;
    }
}

分析:

这种方式是预先加载单例,适合于单例对象初始化非常快,而且占用内存非常小,而且使用频繁的时候。

对于单例初始化的操作耗时比较长而应用对于启动速度又有要求,或者单例的占用内存比较大,再或者单例只是在某个特定场景的情况下才会被使用,需要延迟加载提高性能

volatile关键字作用

1.这个变量不会在多个线程中存在复本,直接从内存读取。

2.这个关键字会禁止指令重排序优化。也就是说,在 volatile 变量的赋值操作后面会有一个内存屏障(生成的汇编代码上),读操作不会被重排序到内存屏障之前。

双重检验锁方式

代码

public class Singleton
{
    private volatile static Singleton singleton = null;
    private Singleton()  {    }
    public static Singleton getInstance()   {
        if (singleton== null)  {
            synchronized (Singleton.class) {
                if (singleton== null)  {
                    singleton= new Singleton();
                }
            }
        }
        return singleton;
    }
}

singleton = new Singleton()这句,这并非是一个原子操作

事实上在 JVM 中这句话大概做了下面 3 件事情。

1.给 singleton 分配内存

2.调用 Singleton 的构造函数来初始化成员变量,形成实例

3.将singleton对象指向分配的内存空间(执行完这步 singleton才是非 null 了)

但是在 JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。

volatile关键字作用

1.这个变量不会在多个线程中存在复本,直接从内存读取。

2.这个关键字会禁止指令重排序优化。也就是说,在 volatile 变量的赋值操作后面会有一个内存屏障(生成的汇编代码上),读操作不会被重排序到内存屏障之前。

内部类方式(优雅)

代码

public class Singleton {
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton (){}
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

分析

老版《Effective Java》中推荐的方式

利用JVM的类加载机制去实现。在很多情况下JVM已经为我们提供了同步控制,比如:

在static{}区块中初始化的数据

访问final字段时

等等

因为在JVM进行类加载的时候他会保证数据是同步的

枚举:(优雅的我快那啥了。。。)

代码

public enum Singleton{
   INSTANCE;
}

分析

新版effective java推荐,非常优雅

使用方式

Singleton singleton = Singleton.INSTANCE;

本文参考了如下两篇博客

http://mp.weixin.qq.com/s?__biz=MzA4NTQwNDcyMA==&mid=403126596&idx=1&sn=101c6d4e363213bcdbe1879edeb08736#wechat_redirect

http://blog.csdn.net/haoel/article/details/4028232

欢迎入群:

公众号IT面试题汇总讨论群

如果扫描不进去,加我微信(rdst6029930)拉你。

扫我微信二维码加我

欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧,都是干货!

微信订阅号二维码如下:

【14】-java的单例设计模式详解的更多相关文章

  1. java的单例设计模式

    java的单例设计模式包括:饿汉设计模式和懒汉设计模式: 步骤: 1.创建一个对象把他设置为私有的成员变量,保证唯一 2.私有构造方法,防止new一个对象. 3.定义一个公开的静态方法,返回第一步创建 ...

  2. Java中如果把构造方法也私有化,如何创建对象?Java的单例设计模式——饿汉式和懒汉式区别

    Java的单例模式——饿汉式 package com.swift; //Java单例设计模式——恶汉式 public class SinglePerson { private String name= ...

  3. 【设计模式】Java之单例设计模式

    1.单例设计模式:一个类只能有一个对象 1.1 创建单例类的步骤: 1.将构造方法私有化 2.创建私有的静态成员变量 3.共有的静态成员方法,提供当前的唯一对象 1.1 创建单例的两种方式: 1.饿汉 ...

  4. Java 之单例设计模式

    设计模式: 对问题行之有效的解决方式, 其实它是一种思想. 单例设计模式 解决的问题:就是可以保证一个类在内存中的对象唯一性. 即单个实例. 比如对于A 和 B 两个程序使用同一个配置信息对象时, A ...

  5. java singleton(单例设计模式)

    单例设计模式的主要作用是: 1.控制资源的使用,我们对资源使用线程同步来实现并发访问. 2.节约资源,我们对一个类只进行一个实例化进行全局的资源访问,节约了内存. 3.作为通信媒介,也是数据共享,可以 ...

  6. 【Java】单例设计模式

    文章目录 单例设计模式 什么是设计模式 单例设计模式 实现 饿汉式 懒汉式 饿汉式与懒汉式的区别 饿汉式 懒汉式 单例模式的应用场景 单例设计模式 什么是设计模式 设计模式是在大量的实践中总结和理论化 ...

  7. Java中的懒汉式单例与饿汉式单例实例详解

    懒汉式单例:线程非安全,当被调用的时候才创建实例,效率较高 public class LazySingleton { private static LazySingleton lazySingleto ...

  8. JAVA:23种设计模式详解(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  9. java之单例设计模式

    什么是设计模式? 设计模式是在大量的实践中总结和理论化之后优选的代码结构.编程风格.以及解决问题的思考方式.设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和探索. 所谓单例 ...

随机推荐

  1. Gradle 的Daemon配置

    最近升级到Android 2.2.2之后,运行之前的项目特别卡,基本上2分钟,好的时候1分半,查询了Android官网的说明说daemon能够加快编译.于是我也尝试开启Daemon. 在Windows ...

  2. TCP的发送系列 — 发送缓存的管理(一)

    主要内容:TCP发送缓存的初始化.动态调整.申请和释放. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 数据结构 TCP对发送缓存的管理是在两个层面上进 ...

  3. EBS总账模块与其他模块数据关联关系

    表名:GL_IMPORT_REFERENCES 说明:总账导入附加信息表 用途:用来追溯从子模块传入总账模块的明细,对于报表开发很有帮助 SQL 语句: select * from gl_je_hea ...

  4. Android的View类介绍-android的学习之旅(十三)

    view概述 android绝大部分UI组件都放在android.view和android.widght包中,android的虽有UI组件都继承了View类. View类还有一个非常重要的子类:Vie ...

  5. (NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 用plist列表文件来表示游戏数据 因为在这个炸弹人游戏中有很多 ...

  6. 如何在Cocos2D游戏中实现A*寻路算法(四)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  7. IDEA中运行KafkaWordCount程序

    1,从spark的example中找到KafkaWordCount.scala文件复制到idea编辑器中,引入包: 2,编辑configuration,     (1)KafkaWordCountPr ...

  8. 在go中使用json作为主要的配置格式

    最近在用go重构,在先前的代码中,我们使用的ini文件进行配置,但是因为很多历史遗留问题,导致配置混乱,维护困难,自然也需要考虑重构了. 通用配置格式 通用的配置格式有很多,常用的就有ini,json ...

  9. flexbox基本原理

    新版的flexbox规范分两部分:一部分是container,一部分是 items. flexbox是一整套布局规范,包含了多个css属性,所以学习起来比`float: left;` 这样简单的布局要 ...

  10. Dynamics CRM2013 Lookup Filtering using addCustomFilter

    dynamics crm中对lookup视图的过滤是一个很平常性的需求,在2011的时候都是用添加自定义视图的方式例如下面这段示例代码 <span style="font-size: ...