Easy单例模式
在学习单例模式前,不妨问自己几个问题:单例模式是怎么来的,单例模式怎么去用?
单例模式是怎么来的?
这就从设计模式起源开始,他是在实际实践中遇到类似情况可以通用经验所得到的总结,一般在其他模块或者方法多次调用类对象,也就是公共模块,用单例模式可以减少内存的消耗。
单例模式怎么去用?
那这个容易,然后很快不到一分钟写完了。
public class singleTonEx01 { private static singleTonEx01 singleTon; public static void main(String args[]) {
singleTonEx01 test1=singleTonEx01.getInstance();
test1.CommonMethod();
} // 防止使用new构造函数实例化对象
private singleTonEx01() { } public static singleTonEx01 getInstance() {
if(null==singleTon)
singleTon=new singleTonEx01();
return singleTon;
} public void CommonMethod() {
System.out.println(getClass().getName());
} }
但这里会有问题,啥问题呢?单线程中是没问题,但是多线程会出现问题,假设两个多线程A与B,A与B同时判断singleTon不为空,那会创建两次,那对于这个问题需要使用同步锁去解决了,下面改造下代码。
public class singleTonEx01 { private static singleTonEx01 singleTon; public static void main(String args[]) {
singleTonEx01 test1 = singleTonEx01.getInstance();
test1.CommonMethod();
} // 防止使用new构造函数实例化对象
private singleTonEx01() { } public static singleTonEx01 getInstance() {
synchronized (singleTonEx01.class) {
if (null == singleTon)
singleTon = new singleTonEx01();
}
return singleTon;
} public void CommonMethod() {
System.out.println(getClass().getName());
} }
这还不是最好的方法,如果是这样的话每个线程都会使用同步锁代码块,使用同步锁其实是消耗资源的,因此,可以再改进下,在外面锁再加个判断,这样一来提高了效率。(推荐这种写法1)
另外,补充一下,实例变量加上volatile的意义。
创建对象可以分解为如下的3行伪代码memory=allocate(); //1:分配对象的内存空间ctorInstance(memory); //2:初始化对象instance=memory; //3:设置instance指向刚分配的内存地址上面3行代码中的2和3之间,可能会被重排序导致先3后2;
public class singleTonEx01 { private volatile static singleTonEx01 singleTon; public static void main(String args[]) {
singleTonEx01 test1 = singleTonEx01.getInstance();
test1.CommonMethod();
} // 防止使用new构造函数实例化对象
private singleTonEx01() { } public static singleTonEx01 getInstance() {
if (singleTon == null) {
synchronized (singleTonEx01.class) {
if (null == singleTon)
singleTon = new singleTonEx01();
}
}
return singleTon;
} public void CommonMethod() {
System.out.println(getClass().getName());
} }
其实还有另外两种方法,一种是不管有没有调用都实例化(俗称恶汉式),另一种是静态内部类的方法(推荐这种写法2),线程安全而且高效
public class singleTonEx02 { private static final singleTonEx02 singleTon=new singleTonEx02(); public static void main(String args[]) {
singleTonEx02 test1 = singleTon;
test1.CommonMethod();
} // 防止使用new构造函数实例化对象
private singleTonEx02() { } public static singleTonEx02 getIntance() {
return singleTon;
} public void CommonMethod() {
System.out.println(getClass().getName());
} }
public class singleTonEx03 { private static class SingleNBClass { private final static singleTonEx03 singleTonEx03=new singleTonEx03(); } public static void main(String args[]) {
singleTonEx03 test1 = singleTonEx03.getIntance();
test1.CommonMethod();
} // 防止使用new构造函数实例化对象
private singleTonEx03() { } public static final singleTonEx03 getIntance() {
return SingleNBClass.singleTonEx03;
} public void CommonMethod() {
System.out.println(getClass().getName());
} }
Easy单例模式的更多相关文章
- java设计模式(二)单例模式 建造者模式
(三)单例模式 单例模式应该是最常见的设计模式,作用是保证在JVM中,该对象仅仅有一个实例存在. 长处:1.降低某些创建比較频繁的或者比較大型的对象的系统开销. 2.省去了new操作符,减少系统内存使 ...
- Java设计模式探讨之单例模式
单例模式是在平时的项目开发中比较常见的一种设计模式,使用比较普遍,网上的资料也是一抓一大把,小Alan也来凑凑热闹,为以后充实点设计模式相关的内容做个简单的开篇. 单例模式是一种创建对象的模式,用于产 ...
- 设计模式之单例模式(C#)
本文来自于本人个人微信公众号,欢迎关注本人微信公众号,二维码附在文章末尾~~~ 一直都特别羡慕能写文章的人,但是由于本人比较懒再加上写文章功底实在是just so so,所以就一搁再搁,最近突然觉得自 ...
- 【编程拾遗】C++的static成员函数与单例模式
static小结 static的引入 static 是C++中非经常常使用的修饰符,它被用来控制变量的存储方式和可见性. 函数内部定义的变量,在程序运行到它的定义处时,编译器为它在栈上分配空间,函数在 ...
- C++ 单例模式总结与剖析
目录 C++ 单例模式总结与剖析 一.什么是单例 二.C++单例的实现 2.1 基础要点 2.2 C++ 实现单例的几种方式 2.3 单例的模板 三.何时应该使用或者不使用单例 反对单例的理由 参考文 ...
- Java项目(5)——单例模式的应用与研究
单例模式是非常别致的一个模式,非常少有人拿它跟其它模式相比,由于,单例模式非常easy,非常特别,作用就是保证一个类有唯一一个实例,并让一个全局变量使得它能被訪问.而保证这个类仅仅被实例化一次的办法就 ...
- Android 设计模式之单例模式
设计模式是前人在开发过程中总结的一些经验,我们在开发过程中依据实际的情况,套用合适的设计模式,能够使程序结构更加简单.利于程序的扩展和维护.但也不是没有使用设计模式的程序就不好.如简单的程序就不用了, ...
- 关于Javakeywordsynchronized——单例模式的思考
精彩的设计模式盛宴刚刚落下帷幕.三天的时间.真是学习到了非常多.当中,遗留的非常多的问题.今天就谈谈synchronized这个keyword.关于对synchronizedkeyword的思考是从单 ...
- C++实现线程安全的单例模式
在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...
随机推荐
- POJ 2139 Six Degrees of Cowvin Bacon
水题,Floyd. #include<cstdio> #include<cstring> #include<algorithm> using namespace s ...
- 在MAC上安装GitHub DeskTop
下载Git工具:下载链接 https://git-scm.com/downloads/ 然后配置Git:配置教程链接 http://jingyan.baidu.com/article/ceb9fb1 ...
- javascript之日期对象
学习要点: 日期对象 将日期对象转换为字符串 将日期对象中的日期和时间转换为字符串 日期对象中的日期 日期对象中的时间 设置日期对象中的日期 设置日期对象中的时间 与毫秒相关的方法 一.日期对象 在j ...
- iOS所有常用证书,appID,Provisioning Profiles配置说明及制作图文教程
概述: 苹果的证书繁锁复杂,制作管理相当麻烦,今天决定重置一个游戏项目中的所有证书,做了这么多次还是感觉很纠结,索性直接记录下来,日后你我他查阅都方便: 首先得描述一下各个证书的定位,作用,这样在制作 ...
- Selenium2+Python:Webdriver API速记手册
由于web自动化常常需要控制浏览器行为和操作页面元素,相关函数又比较多,于是再此记下一份Webdriver API查阅文档以备不时之需. 参考:虫师<Selenium2自动化测试实战>,和 ...
- mongodb学习(三) 安装和基本CRUD
菜鸟啊...先吐槽一下自己 发现mongodb已经升级到2.6标准版了. 服务端最新安装方法: http://www.cnblogs.com/lzrabbit/p/3682510.html 一 准备 ...
- Ubuntu切换默认语言
不得不说,从Ubuntu到Debian,又到CentOS 7,我胡汉三又回来了... 然后又装了个中文版的Ubuntu16.04LTS,不得不说,Ubuntu对中文的支持真的很好 不过,还是不太习惯, ...
- UVa 10132 - File Fragmentation
题目大意:有n个相同的文件,每个文件从中间分为两半,现在给你这2n个文件碎片,求原来完整的文件. 找出文件碎片长度的最大值和最小值,二者相加可得到原来文件的长度len.然后逐个进行拼接,将拼接后长度等 ...
- VS2010中出现无法嵌入互操作类型(转)
针对word或excel操作时,出现VS2010中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法问了度娘,解决方法如出一辙:选中项目中引入的dll,鼠标右键,选择属性,把“嵌入互操作类型”设 ...
- C#子窗口与父窗口交互(使用委托和事件)
目标:在子窗口Form2上单击按钮时向Form1传递一组自定义参数,并显示在父窗口Form1上. 方法:有很多方法,这里只介绍委托和事件的实现方式. 思路:Form2中定义事件,Form1创建Form ...