java设计模式--单列模式
单列模式定义:确保一个类只有一个实例,并提供一个全局访问点。
下面是几种实现单列模式的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设计模式--单列模式的更多相关文章
- Java设计模式——组合模式
JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...
- 3.java设计模式-建造者模式
Java设计模式-建造者模式 在<JAVA与模式>一书中开头是这样描述建造(Builder)模式的: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal repr ...
- Java设计模式-代理模式之动态代理(附源代码分析)
Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...
- Java设计模式——外观模式
JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构
- 【设计模式】Java设计模式 -工厂模式
[设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...
- 【设计模式】Java设计模式 - 原型模式
[设计模式]Java设计模式 - 原型模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...
- 【设计模式】Java设计模式 - 桥接模式
[设计模式]Java设计模式 - 桥接模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...
- 【设计模式】Java设计模式 - 组合模式
Java设计模式 - 组合模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
- 【设计模式】Java设计模式 - 外观模式
Java设计模式 - 外观模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
随机推荐
- 使用JavaScript动态的添加组件
使用JavaScript进行动态的网页窗体组件的添加是一件很方便也很容易实现的事情.话不多说,边看代码边做解释吧. 准备工作 由于html页面中不可以添加java代码,所以我在jsp页面中进行了测试. ...
- C++对C的函数拓展 - 占位参数
函数占位参数 占位参数只有参数类型声明,而没有参数名声明 一般情况下,在函数体内部无法使用占位参数 demo #include <iostream> using namespace std ...
- 1049. Counting Ones (30)
题目如下: The task is simple: given any positive integer N, you are supposed to count the total number o ...
- 远程调试Eclipse插件的设置
1. 被调试方建立一个命令行来运行Eclipse debugEclipse.cmd: eclipse.exe -nl zh_CN -vmargs -XX:+HeapDumpOnOutOfMemoryE ...
- xml解析之使用dom4j的api对xml文件进行CRUD(二)
在使用dom4j的api对xml文件进行CRUD(一)见博客http://blog.csdn.net/qq_32059827/article/details/51524330的基础上,再对做一次练习. ...
- c# 单元测试工程如何取得当前项目路径
前言: C#工程项目中有些配置文件,数据文件等不是C#工程文件,但是程序中需要访问,如果写成绝对路径不利于程序的迁移,所以必须写成相对路径.取得相对路径的方法很多,网上的例子也很多,基本上是七种吧,这 ...
- phantomjs的使用+Java代码+依赖js(兼容Linux和windows版本)
1. 在使用phantomjs的时候需要下载phantomjs,网上有window版本和Linux版本.将phantomjs放在Linux上的指定位置之后(如下面的/home/tpl/phantom ...
- Linux下修改Oracle数据库字符集命令
常见情形:从服务器备份Oracle数据库后再到本地机器上还原Oracle数据库的时候经常会碰见数据库字符编码不一致的情况,可以用以下命令来修改本地的Oracle数据库字符编码,然后顺利还原Oracle ...
- javascript之DOM编程设置节点插入节点
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Linux 操作之基础命令
1.罗列出文件和文件夹 –ls ls 是帮助我们罗列出当前目录下的所有的文件和文件夹,当然了,还可以加上许多选项,最为重要的是所加的参数可以进行组合,起到让人意想不到的效果,下面就是常用的一些ls的及 ...