`
Wanghuidong
  • 浏览: 43811 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
文章分类
社区版块
存档分类
最新评论
  • openFox: 确实,以前只知道编码是个名词,在项目中编码统一就可以了,原来是 ...
    java编码解惑
  • tianzizhi: 前段时间我也看了许多这方面的东西,基本理解了,拿楼主的总结再复 ...
    java编码解惑
阅读更多

最近在一个项目当中遇到了需要一个单实例模型的问题,就认真查了下资料,复习了下java的单例设计

1.饿汉式:在系统启动的时候就讲对象 实例化。

public class Test{

     private static Test instance=new Test();

 

     private Test(){}//必须定义为私有的构造方法 使得不能再外部new一个实例

     public static Test getInstance(){

         return instance;

     }

}

 

2.懒式:在第一次使用到的时候去判断是否为空,然后去实例化

public class Test{

     private static Test instance=null;

 

     private Test(){}//必须定义为私有的构造方法 使得不能再外部new一个实例

     public static Test getInstance(){

         if(instance==null){

              instance=new Test();

          }

         return instance;

     }

}

 

但是 第二种方法只适用于单线程的程序代码当中,不能保证在多线程访问的服务器端程序中运行时候保证单实例。所以在网上出现了将 第二种方法改造为同步锁定的代码如下:

public static synchronized Test getInstance(){

         if(instance==null){

              instance=new Test();

          }

         return instance;

     }

但于此同时也产生了为了保持同步,必须付出昂贵的代价。事实上只有在第一次使用的时候才用到同步,但是如果把同步加到方法上,就在每一次调用获取实例化对象的时候都将产生同步,这样是在服务器端非常耗资源的。

 

一些聪明的程序员为了解决这个问题,发明了一个新的名词:“双重检查锁定”,代码如下

public class Test{

     private static Test instance=null;

 

     private Test(){}//必须定义为私有的构造方法 使得不能再外部new一个实例

     public static Test getInstance(){

         if(instance==null){

              synchronized (Test .class){

                  if(instance==null){

                       instance=new Test();

                   }

              }

        }

         return instance;

     }

}

双重检查锁定背后的理论是完美的。不幸地是,现实完全不同。双重检查锁定的问题是:并不能保证它会在单处理器或多处理器计算机上顺利运行。双重检查锁定失败的问题并不归咎于 JVM 中的实现 bug,而是归咎于 Java 平台内存模型。内存模型允许所谓的“无序写入”,这也是这些习语失败的一个主要原因。

多线程访问的时候会 返回一个非null但是没有被实例化的残缺对象

 

为避免单例中代价高昂的同步,程序员非常聪明地发明了双重检查锁定习语。不幸的是,鉴于当前的内存模型的原因,该习语尚未得到广泛使用,就明显成为了一种不安全的编程结构。重定义脆弱的内存模型这一领域的工作正在进行中。尽管如此,即使是在新提议的内存模型中,双重检查锁定也是无效的。对此问题最佳的解决方案是接受同步或者使用一个 static field

 

本文来自IBM一位开发工程师的日志 详情请参阅:http://www.ibm.com/developerworks/java/library/j-dcl.html 以及 http://ajava.org/course/java/13502.html

分享到:
评论

相关推荐

    java 设计模型之单例模式详解

    本文主要介绍了java 单例模式,单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在,希望能帮助有需要的同学

    单例双检锁

    在努力创建更有效的代码时,Java 程序员们创建了双重检查锁定习语,将其和单例创建模式一起使用,从而限制同步代码量。然而,由于一些不太常见的 Java 内存模型细节的原因,并不能保证这个双重检查锁定习语有效。 ...

    深入分析Java单例模式的各种方案

     Java内存模型的抽象示意图:  所有单例模式都有一个共性,那是这个类没有自己的状态。也是说无论这个类有多少个实例,都是一样的;然后除此者外更重要的是,这个类如果有两个或两个以上的实例的话程序会产生...

    Java初级开发面试题

    Java虚拟机:Java内存模型、垃圾回收、类加载机制等。 常见的Java框架:Spring、Hibernate、Mybatis等。 Java设计模式:单例模式、工厂模式、代理模式等。 网络编程:TCP/IP、HTTP、Web Services等。 数据库相关...

    web bean(中文参考).doc

    和无状态组件模型(例如无状态的会话Bean)或者一个单例模型组件(例如Servlet或者单例Bean)不同,一个Web Bean的不同客户端看到的Web Bean的状态是不同的。客户端所见的状态取决于这个客户端拥有的是哪一个Web ...

    java核心面试技术点

    java 内存模型 ( java memory model ):根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有对象成员变量都储存在主存中,对于所有线程都是共享的。...

    concurrent 多线程 教材

    12 Java单例对象同步问题探讨 13 Java 理论与实践: 描绘线程安全性 (2) 14 编写高效的线程安全类 (2) 15 轻松使用线程 同步不是敌人.mht 16 轻松使用线程 减少争用.mht 17 轻松使用线程 不共享有时是最好的.mht...

    java核心面试

    java 内存模型 ( java memory model ):根据Java Language Specification中的说明, jvm系统中存在一个主内存(Main Memory或Java Heap Memory),Java中所有对象成员变量都储存在主存中,对于所有线程都是共享的。...

    java的23种设计模式

    1、工厂模式 2、建造模式 3、工厂方法模式 4、原始模型模式 5、单例模式 6、适配器(变压器)模式 7、桥梁模式

    Java性能调优实战——覆盖80%以上的Java应用调优场景

    开篇词讲怎样才能做好性能调优02讲如何制定性能调优策略04讲慎重使用正则表达式05讲ArrayList还是LinkedList使用不当性能差千倍07讲深入浅出HashMap的设计与优化08讲网络通信优化之IO模型:如何解决高并发下IO瓶颈09...

    Java 高并发七:并发设计模型详解

    本文主要介绍Java高并发 并发设计模型的知识,这里主要讲解 1. 什么是设计模式 2. 单例模式 3. 不变模式 4. Future模式 5. 生产者消费者,有需要的小伙伴可以参考下

    疯狂JAVA讲义

    11.5.1 Java事件模型的流程 403 11.5.2 事件和事件监听器 405 11.5.3 事件适配器 409 11.5.4 事件监听器的实现形式 411 11.6 AWT的菜单 413 11.6.1 菜单条、菜单和菜单项 414 11.6.2 右键菜单 416 学生提问:...

    JAVA超全面试突击包-答案讲义

    涵含各种重要的JAVA编程知识点,面试突击专用 ...多线程和高并发:包括JAVA的线程模型,同步机制,以及如何编写高并发程序。 设计模式:包括常见的设计模式,如单例模式,工厂模式,观察者模式等,以及它们的使用场景

    Java与模式.清晰.rar

    Java与模式.清晰.rar 第一部分 第1章 模式的简史和形而上学 第2章 统一建模语言UML简介 ...第20章 原始模型(Prototype)模式 第21章 专题:JavaBean的“冷藏”和“解冻” 第四部分 第22章 适配器(Adapter)模式[1]

    实战Java高并发程序设计(第2版)PPT模板.pptx

    5并行模式与算法 5.1探讨单例模式 5.3生产者-消费者模式 5.5future模式 5.2不变模式 5.4高性能的生产者-消费者模式:无锁的实现 5.6并行流水线 01 02 03 04 05 06 实战Java高并发程序设计(第2版)PPT模板全文共25...

    JAVA开发五年程序员简历模版

    1、具备扎实的编程基础,精通Java语言,熟悉JVM,内存模型,并发编程 2、可以灵活运用设计模式,如:单例、工厂、策略、责任链、模板方法等设计模式进行项目开发 3、熟悉Spring、 SpringMVC、SpringBoot、Spring...

    JAVA-SSH面试题

    Java---SSH(MVC) 1. 谈谈你mvc的理解 MVC是Model—View—Controler的简称。即模型—视图—控制器。MVC是一种设计模式,它强制性的把应用程序的输入、处理和输出分开。 MVC中的模型、视图、控制器它们分别担负着...

    java课程设计大作业-基于java构建的CrazyArcade泡泡堂游戏(源码+资源文件+说明文档)

    CrazyArcade泡泡堂游戏,一款用Java编写的JavaSwing游戏程序。 使用了MVC模式,分离了模型、视图和控制器,使得项目结构清晰易于扩展,使用配置文件来设置游戏基本配置,扩展地图人物道具等。同时,该程序编写期间用...

    m3u8-parser:Java的简单HLS播放列表解析器

    该项目的目标是根据实现解析器和一致的Java对象模型。 该解析器与iHeartRadio的非常相似。 主要区别在于: m3u8-parser不会尝试验证播放列表。 您负责创建有效的播放列表。 m3u8-parser使用java.util.Optional...

    java面试800题

    factory工厂模式、prototype原始模型模式、singleton单例模式、builder建造模式 结构模式 facade门面模式、proxy代理模式、adapter适配器(变压器)模式、composite合成模式、decorator装饰模式、bridge桥梁模式、...

Global site tag (gtag.js) - Google Analytics