您的位置:首页 > 编程语言 > Java开发

Java菜鸟学习笔记--设计模式篇(一):Singleton Pattern(单例设计模式)

2013-07-27 18:22 633 查看

什么是Singleton Pattern?

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

Singleton Pattern 动机

对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要

Singleton Pattern 特点

单例模式的三个特点:

1,该类只有一个实例

2,该类自行创建该实例(在该类内部创建自身的实例对象)

3,向整个系统公开这个实例接口

Singleton Pattern 图示



Singleton Pattern 实现

1.懒汉式单例模式实现

1.当然第一步创建一个单利类

//创建一个单例类
public class Singleton{

}


2.单例模式的要求之一就是只有一个子类,让然不能给外界使用构造器了

//1如何做到不让这个类只有一个实例?--首先把构造器访问权限设为private
private Singleton(){
//里面我爱做什么是我的事情
}


3.构造器都没了你让我怎么创建实例?--你不用创建~我给你就行

public static Singleton getInstance(){

return new Singleton();

}
4.可是这样我想要几个调用几次,这就是你说的单例?--没有,工作还没弄到一半呢,基本原则就是我创建好了给你,

而且是创建唯一一个实例,还是你需要时候我才创建给你。先在类里面生命个对象

//6.我里面声明一个对象,先不new,在方法里面new,当然是要设为static的
private static Singleton uniqueInstance=null;//uniqueInstance表示独一无二的实例


5.然后咱在修改方法

public static Singleton getInstance(){

//return new Singleton();//4.那你每次调用这个都可以得到新的实例,没区别了啊
//5.当然不能直接返回咯,加以个判断条件,我就创建一个唯一实例给你
//7.判断调用,第一次调用当然为对象当然为null,那我new一个给你
if(uniqueInstance==null){

uniqueInstance=new Singleton();

}
//8.如果第一次上面就自动new一个,第二次到第n次,我就返回之前那个给你
return uniqueInstance;

}


6.这样是不是就可以实现单例模式了?我们测试一下吧

public static void main(String[] args){

//9.测试是不是同一个类
Singleton my=Singleton.getInstance();
Singleton your=Singleton.getInstance();
if(my==your){

System.out.println("my 和 your 指向同一个对象空间!");
//输出了:my 和 your 指向同一个对象空间!

}

}


7.这样就可以实现单例模式了!完整代码

//经典的单例模式(Singleton pattern)
package me.singleton;

//创建一个单例类
public class Singleton{

//6.我里面声明一个对象,先不new,在方法里面new,当然是要设为static的 private static Singleton uniqueInstance=null;//uniqueInstance表示独一无二的实例

//1如何做到不让这个类只有一个实例?--首先把构造器访问权限设为private private Singleton(){ //里面我爱做什么是我的事情 }
//2.把构造都设为private了,那你怎么得到对象?--暴露个方法给你咯

public static Singleton getInstance(){

//return new Singleton();//4.那你每次调用这个都可以得到新的实例,没区别了啊
//5.当然不能直接返回咯,加以个判断条件,我就创建一个唯一实例给你
//7.判断调用,第一次调用当然为对象当然为null,那我new一个给你
if(uniqueInstance==null){

uniqueInstance=new Singleton();

}
//8.如果第一次上面就自动new一个,第二次到第n次,我就返回之前那个给你
return uniqueInstance;

}
public static void main(String[] args){

//9.测试是不是同一个类
Singleton my=Singleton.getInstance();
Singleton your=Singleton.getInstance();
if(my==your){

System.out.println("my 和 your 指向同一个对象空间!");
//输出了:my 和 your 指向同一个对象空间!

}

}

}


1.多线程下的懒汉式,饿汉式设计模式

/*
1.两种单利设计模式【饿汉式,懒汉式】

*/
package me.threaddemo3;

//饿汉式
class Demo{

private static final Demo s=new Demo();
private Demo(){}

public static Demo getInstance(){

return ;

}

}
//懒汉式
class Single{

private static Single s=null;
private Single(){}

public static Single getInstance(){

//对比饿汉式,懒汉式多了延迟加载
if(s==null){
/*

当A线程进入这里,然后挂起,B线程可以进来,然后AB可以同时new两个对象
这样n多个多线程就出安全问题了,所以有必要加上同步

*/
s=new Single();

}/*

*/
return s;
}

}
//添加了同步代码块的懒汉式单例模式
class SyncSingle{

private static SyncSingle s=null;
private Single(){}

//同步synchronized不应该放函数生命这里,不然太低效率了
public static SyncSingle getInstance(){

if(s==null)
synchronized(SyncSingle.class){

if(s==null){
//当A线程进来这里挂起后,BCDE等等线程都进不来了。
//当A离开后,B进来也不符合条件了
//C的话连第一个判断条件也不满足。
s=new Single();

}
/*
这样就有了安全性,通过同步代码块和双判断语句
同时也提高了效率
*/

}
return s;
}

}


作者:YangGan

出处:http://blog.csdn.net/incyanggan

本文基于署名
2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名Yanggan(包含链接).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: