(@WhiteTaken)设计模式学习——单例模式
单例模式,个人理解就是,使用了这个模式,可以保证一个类只生成唯一的实例对象。就是在整个程序中,这个类只存在一个实例对象。
GoF对单例模式的定义:保证一个类,只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。
客户端的代码用来测试,获取到的实例只有一个。直接上代码。
public class MainClass {
public static void main(String[] args) {
Person person1=Person.getPerson();//获取Person对象
Person person2=Person.getPerson();//获取Person对象
person1.setName("Tom");
person2.setName("WhiteTaken");//如果两个获取的到的对象的实例,是同一实例,那么打印出来的名字应该是一样的。
System.out.println(person1.getName());
System.out.println(person2.getName());
}
}
如果不是单例模式,而仅仅是创建了几个对象 ,那么两次打印的结果,将会是两个不同的名字。
而单例模式的情况,获取的到的是同一个对象,那么两次打印的结果,将是第二次赋值的结果。
单例测试结果如下。
好,上面是测试结果,那么单例模式是怎么实现的呢。
我学习到的三种单例模式的创建方法。
1.直接用final方式创建。只要类执行,就会创建这样一个对象。
代码如下。
public class Person {
private String name;
public static final Person perSon= new Person();//注意此处的final
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
//构造函数私有化
private Person(){ }
//获取对象的方法,final实现
public static Person getPerson(){
return perSon;
}
}
通过final关键字,保证perSon只被赋值一次,即值生成一次对象。
2.第二种方式,通过在获取对象的方法中判断person是否为null,如果不存在,则实例化person,如果存在,则直接返回person实例。
public class Person2 {
private String name;
private static Person2 perSon;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造函数私有化
private Person2(){ }
//获取对象的方法,单线程模式可用
public static Person2 getPerson(){
if(perSon==null){
return perSon=new Person2();
}
return perSon;
}
}
以上方法是实现单例模式的第二种方法,但是此种方法有一个天然的劣势,就是只适合单线程开发。
多线程的话,如果两个线程同时访问这个方法的话,返回的person对象可能会出现不一样的情况 ,那就不是单例了。
如果使用同步方法的话(synchronized),多线程的情况下会造成线程等待,影响效率。
3.第三种方式是通过双重检查的方式实现单例。
双重判断,通过两次判断null,能够确保在多线程下,只生成一个单例。
public class Person4 {
private String name;
private static Person4 perSon;
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
//构造函数私有化
private Person4(){ }
//获取对象的方法,双重检查
public static Person4 getPerson(){
if(perSon==null){
synchronized (Person4.class) {
if(perSon==null){
return perSon=new Person4();
}
}
}
return perSon;
}
}
这样就完成单例模式的简单应用。
要想达到学以致用,真的很难,工作久了,很多东西都忘了。。。单例模式写的一个小例子,加强理解。
需要注意:只创建了一次对象。
class Program
{
static void Main(string[] args)
{
Console.WriteLine("================测试单例模式=========begin======");
Test tst = GetAllTest.GetTest();
tst.TestPrint();
Test tst2 = GetAllTest.GetTest();
tst2.TestPrint();
Console.WriteLine("================测试单例模式=========end========");
Console.Read();
}
} class Test
{
public Test(){}
public void TestPrint()
{
Console.WriteLine("单例模式打印结果");
}
} class GetAllTest
{
private static Test ts;
public static Test GetTest()
{
if(ts == null)
{
Console.WriteLine("创建Test对象过程");
ts = new Test();
} return ts;
}
}
打印结果:
好好努力,提高自己!!!
(@WhiteTaken)设计模式学习——单例模式的更多相关文章
- java设计模式学习 ----- 单例模式(Singleton)
单例模式(Singleton) 单例对象(Singleton)是一种经常使用的设计模式. 在Java应用中,单例对象能保证在一个JVM中,该对象仅仅有一个实例存在.单例模式也分三种:懒汉式单例.饿汉式 ...
- GoF设计模式学习-单例模式
1.目的 控制实例的个数,类设计者应该保证只有一个实例,不能将此责任[只有一个实例]强制交给类使用者. 2.整体实现 1.单线程单例模式的实现. using System; using System. ...
- java设计模式学习-单例模式
java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供.”单例模式可以保证一个应用中有且只有一个实例,避免了资源的浪费和多个实例多次调用导致出错. 单例模式有以下特点: 1.单 ...
- C#设计模式学习笔记-单例模式随笔
最近学习 设计模式,从单例模式入手 啥是单例模式: 要实现一个单例类的话,首先,肯定是不能让用户自行生产的,那就是说明不能让用户new,所以,就必须把构造函数设置成为私有的 因为静态变量的生命周期跟整 ...
- C#设计模式学习笔记-单例模式(转)
C#设计模式学习笔记-单例模式 http://www.cnblogs.com/xun126/archive/2011/03/09/1970807.html 最近在学设计模式,学到创建型模式的时候,碰到 ...
- Java设计模式学习笔记(五) 单例模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 使用单例模式的原因 以Windows任务管理器为例,在Windows系统中,任务管理器是唯 ...
- 【C++深入浅出】设计模式学习之单例模式
但凡成为大家公认的模式,都是有一些不可小觑的威力,今天分享一个简单的设计模式:单例模式. 单例模式用于一些只希望有一个实例的类或者只希望执行一次的操作:校长只能有一个.老板只能有一个.用户点击弹窗只希 ...
- Java设计模式学习01——单例模式(转)
原地址:http://blog.csdn.net/xu__cg/article/details/70182988 Java单例模式是一种常见且较为简单的设计模式.单例模式,顾名思义一个类仅能有一个实例 ...
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
随机推荐
- IO之同步、异步、阻塞、非阻塞
Stevens在文章中一共比较了五种IO Model: blocking IO nonblocking IO IO multiplexing signal driven IO ...
- HTML 5终于定稿,八年后我们再一次谈谈怎么改变世界
我们第一次谈论 HTML5 要改变世界大概是因为乔布斯,他坚持在 iOS 上不兼容 Flash,在 Adobe 统治多媒体开发的那个年代,这需要付出极大的勇气.这么多年过去了,虽然所有人都在谈论 HT ...
- List的输出方法
1.for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i));} 2.List list = new ...
- Tessnet2图片识别
验证码识别据说可以用C#图像识别类库Tessnet2来实现,Tessnet2源于目前Google维护的开源项目Tesseract2.本文将对此传说进行验证,含验证结果与验证方法. 1. 验证结果 —— ...
- C语言-数组
C语言中使用数组来存储相同类型的大批量数据. 数组: 数组名:起名规则和变量名一样: 定义数组:数组每个元素存储的数据类型+数组名[常量(时表示数组分配存储数据类型的个数也就是长度)]={每个元素,以 ...
- vuejs 子组件传递父组件的第二种方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- leetcode-位运算
位运算可以大大减小算法空间复杂度,提高效率,很巧妙! 先说一下位运算的简单用法 1. 按位与 & 用途:清零,取一个数中的某些指定位,保留一个数中的某些指定位 2. 按位或 | 用途:将一个数 ...
- MVC笔记2:mvc+jquery.validate.js 进行前端验证
1.引用如下js和css 代码 <link href="@Url.Content("~/Content/Site.css")" rel="sty ...
- 如何使用python timeit模块使用实践
其实平时使用测试应用运行时间的情况 细算一下还真的很少.很久没有做性能优化的工作,不管是cProfile还是timeit模块都已经生疏了很久没有使用,我在以前的文章里面有提到过cPfile的性能测试使 ...
- iOS 之 设置横竖屏及ViewWillAppear及视图与导航控制器嵌套时的不同反应
设置横竖屏不成功,可能跟所在导航控制器有关 视图没有导航控制器时,又有可能不调用ViewWillAppear,这是我遇到的问题.