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 ...
随机推荐
- Eclipse perl的IDE环境插件-EPIC
前提:1.安装好perl环境:ActivePerl(验证方法:cmd中输入 perl -v 看是否有反应~) 2.安装Eclipse 3.0以上版本 可选:安装PadWalker包,主要是全局变量跟踪 ...
- ubuntu下如何安装和卸载wine-qq
1.安装wine 按ctrl+alter+T打开终端输入以下两条命令 sudo apt-get update sudo apt-get install wine 安装时间有点长,请耐心的等候 2.按钮 ...
- LPC1768的SPI通讯
SPI是一种全双工串行接口,可处理多个连接到指定总线上的主机和从机.在数据传输过程中总线上只能有一个主机和一个从机通信.在数据传输中,主机总是会向从机发送一帧8到16个位的数据,而从机也总会向主机发送 ...
- IOS手势识别,捏合,旋转,轻扫等
ref:http://blog.csdn.net/rechard_chen/article/details/51769972 //点按手势的创建,这里需要实现响应事件的方法 UITapGestur ...
- python实现断点续传下载文件
最近的任务里有一个功能是要我从日志服务器实时跟新日志到本地,日志在不断新增内容就需要我隔一段时间从上次下载的位置继续下载,并写入本地文件上次写完的位置后面. headers = {'Range': ' ...
- MongoDB和MySQL的区别
http://www.cnblogs.com/caihuafeng/p/5494336.html MongoDB(文档型数据库):提供可扩展的高性能数据存储 一. 1.基于分布式文件存储 2.高负载情 ...
- js extend的实现
var obj = { a: "aaaaaa" }; var obj1 = { b: "bbbbbb" }; Object.extend = function ...
- UVa 495 - Fibonacci Freeze
题目大意:计算斐波那契数列的第n项. 由于结果会很大,要用到大数.开始本来想节省空间的,就没用数组保存,结果超时了... import java.io.*; import java.util.*; i ...
- java中的Set的使用以及各种遍历方法(较为全面)
1. 概述 Java 中的Set和正好和数学上直观的集(set)的概念是相同的.Set最大的特性就是不允许在其中存放的元素是重复的.根据这个特点,我们就可以使用Set 这个接口来实现前面提到的关于商品 ...
- UVa 10427 - Naughty Sleepy Boys
题目大意:从1开始往后写数字,构成一个如下的字符串 123456789101112... .求第n位的数字是多少. 找规律,按数字的位数可以构建一个类似杨辉三角的东西,求出第n位是哪个数的第几位即可. ...