转载请注明出处:http://blog.csdn.net/ns_code/article/details/17359719

特点

单例模式的特点:

1、只能有一个实例;

2、必须自己创建自己的一个实例;

3、必须给所有其他对象提供这一实例。

饿汉式单例模式

也称为预先加载法,实现方式如下:

class Single
{
private Single()(
Syustem.out.println("ok");
)
private static Single instance = new Single(); public static Single getInstance(){
return instance;
}
}

优点:线程安全,调用时反应速度快,在类加载的同时已经创建好了一个静态对象;

缺点:资源利用效率不高,可能该实例并不需要,但也被系统加载了。

懒汉式单例模式

也称为延迟加载法,实现方式如下:

public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {} public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}

延迟加载法在适用于单线程环境,它不是线程安全的,引入多线程时,就必须通过同步来保护getInstance()方法,否则可能会返回LazySingleton的两个不同实例。比如,一个线程在判断instance为null后,还没来得及创建新的instance,另一个线程此时也判断到instance为null,这样两个线程便会创建两个LazySingleton实例。

可以将getInstance()方法改为同步方法,这样便可以避免上述问题,改进后的单例模式实现如下:

public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {} public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}

优点:资源利用率高,不执行getInstance就不会被实例。

缺点:第一次加载时反应不快,多线程使用不必要的同步开销大

这里的缺点主要是:每次调用getInstance()方法时,都要同步,而且很多时候的同步是没必要的,这将会极大地拖垮性能(尤其在需要多次调用getInstance方法的地方)。

DCL单例模式

针对延迟加载法的同步实现所产生的性能低的问题,我们可以采用DCL,即双重检查加锁(Double Check Lock)的方法来避免每次调用getInstance()方法时都同步。实现方式如下:

public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {} public static LazySingleton getInstance() {
if (instance == null) {
synchronized(LazySingleton.class){
if(instance == null){
instance = new LazySingleton();
}
}
}
return instance;
}
}

优点:资源利用率高,不执行getInstance就不会被实例,多线程下效率高。

缺点:第一次加载时反应不快,由于java 内存模型一些原因偶尔会失败,在高并发环境下也有一定的缺陷,虽然发生概率很小。

static内部类单例模式

该方法是为了解决DCL方法在并发环境中的缺陷而提出的,关于DCL在并发编程中存在的问题可以参考这篇文章:http://blog.csdn.net/ns_code/article/details/17348313的后半部分,其实现方式如下:

class Single
{
private Single()(
Syustem.out.println("ok");
) private static class InstanceHolder{
private static final Singlet instance = new Single();
} public static Single getInstance(){
return InstanceHolder.instance;
}
}

优点:线程安全,资源利用率高,不执行getInstance就不会被实例。

缺点:第一次加载时反应不快。

这里针对最后一种方法补充以下基本知识点:类级内部类(有static修饰的成员内部类)相当于其外部类的成员,只有在第一次使用时才会被装载,而不会在类加载器加载其外部类的时候被装载。因此,资源利用率高。

总结:在Java中由于会涉及到并发编程,考虑到效率、安全性等问题,一般常用饿汉式单例模式或static内部类单例模式,二者优缺点刚好颠倒过来,因此要根据具体情况来使用。

参考资料:http://blog.csdn.net/ns_code/article/details/17348313

http://write.blog.csdn.net/postlist/0/all/draft

http://www.myexception.cn/software-architecture-design/1235112.html

http://m.blog.csdn.net/blog/codezjx/8883599

http://blog.sina.com.cn/s/blog_6d2890600101gb8x.html

【设计模式】单例设计模式的N中Java实现方法的更多相关文章

  1. java软件设计模式——单例设计模式中的【饿汉式】与 【懒汉式】示例

    以下为单例设计模式中的两种经典模式的代码示意: 单例设计模式(spring框架IOC,默认创建的对象都是单例的): 饿汉式: public class SingleClass { private Si ...

  2. 【java】设计模式-单例设计模式

    单例设计模式:解决一个类在内存中是存在一个对象的问题.当需要该事物的对象在内存中唯一时,将以下三步添加即可. 思想:想要保证对象唯一1.为了避免其他程序过多的建立该类对象,先禁止其他程序建立该类对象2 ...

  3. java设计模式——单例设计模式

    /*设计模式:对问题行之有效的解决方式.其实它是一种思想. 1,单例设计模式.    解决的问题:就是可以保证一个类在内存中的对象唯一性. 必须对于多个程序使用同一个配置信息对象时,就需要保证该对象的 ...

  4. Java设计模式—单例设计模式(Singleton Pattern)全然解析

    转载请注明出处:http://blog.csdn.net/dmk877/article/details/50311791 相信大家都知道设计模式,听的最多的也应该是单例设计模式,这种模式也是在开发中用 ...

  5. java设计模式-----单例设计模式

    设计模式是个很高深的东西,我也是略懂皮毛,下面让我用最简洁易懂的语言描述下单例设计模式吧. 一些人总结出来用来解决特定问题的固定的解决方案. 解决一个类在内存中只存在一个对象,想要保证对象的唯一. 1 ...

  6. 设计模式——单例设计模式(C++实现)

    #ifndef SINGLETONHOLDER_INC #define SINGLETONHOLDER_INC template<class T> class SingletonHolde ...

  7. 【Java】单例设计模式

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

  8. 初学者学Java设计模式(一)------单例设计模式

    单例设计模式 单例设计模式是指一个类只会生成一个对象,优点是他可以确保所有对象都访问唯一实例. 具体实现代码如下: public class A { public static void main(S ...

  9. 适配器、工厂模式、线程池、线程组、互斥锁、Timer类、Runtime类、单例设计模式(二十四)

    1.多线程方法 * Thread 里面的俩个方法* 1.yield让出CPU,又称为礼让线程* 2.setPriority()设置线程的优先级 * 优先级最大是10,Thread.MAX_PRIORI ...

  10. 包和访问权限修饰符,.单例设计模式,.Object类常用方法,.内部类

    1.包和访问权限修饰符 1.1 包 为什么要导包? 将字节码文件(.class)文件进行分类存放 --->包 其实就是文件夹 import java.util.Arrays; 包的划分规则 方案 ...

随机推荐

  1. sjtu1591 Count On Tree

    Description Crystal家有一棵树.树上有\(n\)个节点,编号由\(1\)到\(n\)(\(1\)号点是这棵树的根),两点之间距离为1当且仅当它们直接相连.每个点都有各自的权值,第\( ...

  2. treeview 点击时选中节点

    private void tv_WebList_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { Point clickPo ...

  3. angular2地址栏路由配置

    一步一步route过去可以,地址栏直接写url怎么就找不到了呢? 这关乎于Nodejs的express路由规则(http://hm4123660.iteye.com/blog/2195035) exp ...

  4. Javascript实现打字效果

    伤感的 学期末 今天是这学期的最后一天,考完了最后一门数学,明天我们就要各自为自己的暑假打算打算了,所以趁着大家还没走一起出去打了打篮球,玩了玩轮滑,很累但是很开心,最大的感触莫过于忧伤额,明年我或许 ...

  5. 优化函数式编程:向 PHP 移植 Clojure 函数

    许多通用程序设计语言试图兼容大多数编程范式,PHP 就属于其中之一.不论你想要成熟的面向对象的程序设计,还是程序式或函数式编程,PHP 都可以做到.但我们不禁要问,PHP 擅长函数式编程吗?本文系国内 ...

  6. bulkTransfer通讯必须注意的问题:bulk buffer size(16K)

    Android USB host与HID使用bulkTransfer通讯接收和发送的数据长度不会超过16384,这个问题困扰了我很长一段时间,终于发现问题所在,不是出在我的程序设计,也不是硬件的发送/ ...

  7. OpenSSL 与 SSL 数字证书概念贴

    SSL/TLS 介绍见文章 SSL/TLS原理详解(http://seanlook.com/2015/01/07/tls-ssl). 如果你想快速自建CA然后签发数字证书,请移步 基于OpenSSL自 ...

  8. java路径中的空格问题(转)

    java路径中的空格问题 1. URLTest.class.getResource("/").getPath(); URLTest.class.getResource(" ...

  9. java中path和classpath

    Path 路径,是java编译时需要调用的程序(如java,javac等)所在的地方; CLASSPATH的作用是指定查找类的路径:当使用java命令执行一个类(类中的main方法)时,会从class ...

  10. Spring读取加密属性文件处理

    引言:Spring框架俨然已经是目前Java WEB项目开发的一个宠儿,更有人将Spring, Struts,和Hibernage称之为Java WEB项目开发的3件利器.Spring的依赖.注入.A ...