单列模式定义:确保一个类只有一个实例,并提供一个全局访问点。

下面是几种实现单列模式的Demo,每个Demo都有自己的优缺点:

Demo1:

/**
* 单列模式需要满足下面三个条件:
* 1.私有的构造函数
* 2.私有的引用变量
* 3.公开的静态方法(唯一获取该类单个实例的地方)
*
* @author Administrator
*/
public class AmericaPresident
{
private static AmericaPresident thePresident; /**
* 功能:私有的构造函数
*/
private AmericaPresident()
{
} /**
* 功能:返回AmericaPresident对象
* @return
*/
public static AmericaPresident getPresident()
{
if(thePresident == null)
{
thePresident = new AmericaPresident();
} return thePresident;
}
} Demo1 在多线程的时候可能会出现一些程序上的bug

Demo2:

为了解决上面Demo1在多线程时候的bug,可以做出以下的修改:

/**
* 单列模式需要满足下面三个条件:
* 1.私有的构造函数
* 2.私有的引用变量
* 3.公开的静态方法(唯一获取该类单个实例的地方)
*
* @author Administrator
*/
public class AmericaPresident
{
private static AmericaPresident thePresident; /**
* 功能:私有的构造函数
*/
private AmericaPresident()
{
} /**
* 功能:返回AmericaPresident对象
* @return
*/
public static synchronized AmericaPresident getPresident()
{
if(thePresident == null)
{
thePresident = new AmericaPresident();
} return thePresident;
}
} 通过增加synchronized 关键字到getPresident()方法中,我们迫使每个线程在进入这个方法之前,
要先等候别的线程离开该方法。也就是说,不会有两个线程可以同时进入这个方法。 Demo2解决了多线程下的程序bug,但是又带了一个新的问题,同步一个方法可能造成程序执行效率
下降100倍。

Demo3:

/**
* 单列模式需要满足下面三个条件:
* 1.私有的构造函数
* 2.私有的引用变量
* 3.公开的静态方法(唯一获取该类单个实例的地方)
*
* @author Administrator
*/
public class AmericaPresident
{
private static AmericaPresident thePresident = new AmericaPresident(); /**
* 功能:私有的构造函数
*/
private AmericaPresident()
{
} /**
* 功能:返回AmericaPresident对象
* @return
*/
public static synchronized AmericaPresident getPresident()
{
return thePresident;
}
} Demo3使用"急切"创建实例,而不用延迟实例化的做法,如果应用程序总是创建并使用单列实例,或者
在创建和运行方面的负担不太繁重,就可以用"急切"的方法来创建单列。
利用这个做法,我们可以依赖JVM在加载这个类时马上创建此唯一的单列实例,JVM保证在任何线程
访问thePresident静态变量之前,一定先创建此实例。

Demo4:

用"双重检验加锁",在getPresident()中减少使用同步。

利用双重检查加锁(double-checked locking),首先检查是否实例已经创建了,如果尚未
创建,"才"进行同步。这样一来,只有第一次会同步。 /**
* 单列模式需要满足下面三个条件:
* 1.私有的构造函数
* 2.私有的引用变量
* 3.公开的静态方法(唯一获取该类单个实例的地方)
*
* @author Administrator
*/
public class AmericaPresident
{
private volatile static AmericaPresident thePresident; /**
* 功能:私有的构造函数
*/
private AmericaPresident()
{
} /**
* 功能:返回AmericaPresident对象
* @return
*/
public static synchronized AmericaPresident getPresident()
{
if(thePresident == null)//检查实例,如果不存在,就进入同步区块
{
synchronized(AmericaPresident.class)//注意,只有第一次才彻底执行这里的代码
{
if(thePresident == null)//进入区块后,再检查一次,如果还是Null,才创建实例。
{
thePresident = new AmericaPresident();
}
}
}
return thePresident;
}
} volatile关键字确保:当thePresident变量被初始化成AmericaPresident实例时,多个线程正确
处理thePresident变量。 如果性能是你关注的重点,那么这个做法可以帮你大大地减少getPresident()的时间消耗。

java设计模式--单列模式的更多相关文章

  1. Java设计模式——组合模式

    JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...

  2. 3.java设计模式-建造者模式

    Java设计模式-建造者模式 在<JAVA与模式>一书中开头是这样描述建造(Builder)模式的: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal repr ...

  3. Java设计模式-代理模式之动态代理(附源代码分析)

    Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...

  4. Java设计模式——外观模式

    JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  5. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

  6. 【设计模式】Java设计模式 - 原型模式

    [设计模式]Java设计模式 - 原型模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...

  7. 【设计模式】Java设计模式 - 桥接模式

    [设计模式]Java设计模式 - 桥接模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...

  8. 【设计模式】Java设计模式 - 组合模式

    Java设计模式 - 组合模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

  9. 【设计模式】Java设计模式 - 外观模式

    Java设计模式 - 外观模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

随机推荐

  1. 使用JavaScript动态的添加组件

    使用JavaScript进行动态的网页窗体组件的添加是一件很方便也很容易实现的事情.话不多说,边看代码边做解释吧. 准备工作 由于html页面中不可以添加java代码,所以我在jsp页面中进行了测试. ...

  2. C++对C的函数拓展 - 占位参数

    函数占位参数 占位参数只有参数类型声明,而没有参数名声明 一般情况下,在函数体内部无法使用占位参数 demo #include <iostream> using namespace std ...

  3. 1049. Counting Ones (30)

    题目如下: The task is simple: given any positive integer N, you are supposed to count the total number o ...

  4. 远程调试Eclipse插件的设置

    1. 被调试方建立一个命令行来运行Eclipse debugEclipse.cmd: eclipse.exe -nl zh_CN -vmargs -XX:+HeapDumpOnOutOfMemoryE ...

  5. xml解析之使用dom4j的api对xml文件进行CRUD(二)

    在使用dom4j的api对xml文件进行CRUD(一)见博客http://blog.csdn.net/qq_32059827/article/details/51524330的基础上,再对做一次练习. ...

  6. c# 单元测试工程如何取得当前项目路径

    前言: C#工程项目中有些配置文件,数据文件等不是C#工程文件,但是程序中需要访问,如果写成绝对路径不利于程序的迁移,所以必须写成相对路径.取得相对路径的方法很多,网上的例子也很多,基本上是七种吧,这 ...

  7. phantomjs的使用+Java代码+依赖js(兼容Linux和windows版本)

    1.  在使用phantomjs的时候需要下载phantomjs,网上有window版本和Linux版本.将phantomjs放在Linux上的指定位置之后(如下面的/home/tpl/phantom ...

  8. Linux下修改Oracle数据库字符集命令

    常见情形:从服务器备份Oracle数据库后再到本地机器上还原Oracle数据库的时候经常会碰见数据库字符编码不一致的情况,可以用以下命令来修改本地的Oracle数据库字符编码,然后顺利还原Oracle ...

  9. javascript之DOM编程设置节点插入节点

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. Linux 操作之基础命令

    1.罗列出文件和文件夹 –ls ls 是帮助我们罗列出当前目录下的所有的文件和文件夹,当然了,还可以加上许多选项,最为重要的是所加的参数可以进行组合,起到让人意想不到的效果,下面就是常用的一些ls的及 ...