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 ...
随机推荐
- ZOJ 3929 Deque and Balls
答案=所有情况中总共递减次数*2 放完i个和放完i-1个之间的递减次数是可以递推的. 有一部分是放完i-1个之后产生的,还有一部分是放完第i个之后新产生的. 注意减去多加的部分. 2的i次方可以打个表 ...
- Photoshop 画基本图形
作者:zccst 1,画三角形 按下“U”选择“多边形工具”(是个六边形的图标),在上方的菜单栏中的“边”后面输入“3”,然后在画布中拖动就是三角形了,画好后按下CTRL+ENTER键转化成选区,然后 ...
- IOS数据库FMDB增、删、改、查的使用【原创】
http://blog.it985.com/13588.html IOS数据库FMDB增.删.改.查的使用[原创] FMDB是一个XCODE的中一个轻量级的数据库,用于将网络资源存储在本地.所以,FM ...
- eclipse注释模板设置(未整理)
Window --> Java --> Code Style --> Code Templates --> Comments --> types --> Edit ...
- IOS之富文本编辑
之前做项目时遇到一个问题: 使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结 ...
- Java编程思想非主流知识点
1. Java中的多态性理解(注意与C++区分) Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意 ...
- 再次写了第一个servlet
费时2小时,熟悉tomcat和编写了第一个servlet
- Android实现渐显按钮的左右滑动效果
本示例演示在Android中实现带渐显按钮的左右滑动效果. 关于滑动效果,在我的上一篇博文中提到过,有兴趣的朋友可以访问: http://www.cnblogs.com/hanyonglu/archi ...
- limesurvey设置短调查问卷url
If you want to use fancy URLs and so not have /index.php in every URL please edit /application/confi ...
- 使用django-compressor压缩静态文件
Reference:http://blog.csdn.net/permike/article/details/52355095 在网站开发阶段,对于静态资源文件比如JS,CSS等文件都是未经过压缩合并 ...