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 ...
随机推荐
- HDU 5624 KK's Reconstruction
这题目测是数据水了.我这种暴力写法显然是可以卡超时的. 假设有2000个点,15000条边,前面10000条不能构成树,后面5000条可以,这种数据显然可以卡超时. #include <stdi ...
- cf Round 594
A.Warrior and Archer(思维) 战士一定会ban掉当前边缘的位置.而战士和射手就会选择剩下的最远的两点.我们让剩下的最远的两点最近就达到了均衡.于是我们枚举战士ban掉的边缘,ban ...
- ios 字体设计
ref: http://ju.outofmemory.cn/entry/217705 ref:http://gold.xitu.io/entry/57958a41128fe10056be13b1 下面 ...
- css(二) block,inline和inline-block概念和区别
转: http://www.cnblogs.com/KeithWang/p/3139517.html 总体概念 block和inline这两个概念是简略的说法,完整确切的说应该是 block-leve ...
- UVa 543 - Goldbach's Conjecture
题目大意:给一个偶数,判断是否是两个素数的和. 先用sieve方法生成一个素数表,然后再进行判断即可. #include <cstdio> #include <vector> ...
- 关于String的相关常见方法
package Stirng类; /** * String 常见的相关方法摘要 * @author Administrator * */ public class DemoStringMethod { ...
- [Angular Tutorial]PhoneCat Tutorial App
(注:曾经在<不敢止步>一书中看到学到一个观点,作者认为学习一门技术最好的方法就是翻译某部领域书籍.这里我决定做一次尝试,接下来花1个月左右时间,将Angular Tutorial Pho ...
- javascript AOP
Function.prototype.bind = function(b) { var a = this; return function() { a.apply(b, arguments) } }; ...
- Webx MVC分析(转)
Webx框架:http://openwebx.org/ petstore:webx3/webx-sample/petstore/tags/3.0/petstore 编译之后:mvn jetty:run ...
- Delphi的时间与字符串函数代码示例
[delphi] view plaincopyprint? SysUtils.StrToDate(); SysUtils.StrToDateDef(); SysUtils.TryStrToDate() ...