24种设计模式--单例模式【Singleton Pattern】

  这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此广泛,如此的有人缘,单例就是单一、独苗的意思,那什么是独一份呢?你的思维是
独一份,除此之外还有什么不能山寨的呢?我们举个比较难复制的对象:皇帝
  中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝应用和昨天、前天的一样(过渡期的不考虑),大臣磕完头,抬头一看,嗨,还是昨天那个皇帝,单例模式,绝对的单例模式。
  先看类图:
  

然后我们看程序实现,先定一个皇帝:

 1 package com.iadmob.singleton;
 2
 3 /**
 4  * @author http://www.cnblogs.com/initial-road/
 5  * 中国的历史上一般都是一个朝代一个皇帝,有两个皇帝的话,必然要PK出一个皇帝出来
 6  */
 7 public class Emperor {
 8     //定义一个皇帝放在那里,然后给这个皇帝名字
 9     private static Emperor emperor = null;
10
11     private Emperor(){
12         //世俗和道德约束你,目的就是不让你产生第二个皇帝
13     }
14
15     public static Emperor getInstance(){
16         if(emperor == null){
17             emperor = new Emperor();
18         }
19         return emperor;
20     }
21
22     //皇帝叫什么名字呀
23     public static void emperorInfo(){
24         System.out.println("我就是皇帝某某某....");
25     }
26 }
27
28 然后定义大臣:
29 package com.iadmob.singleton;
30
31 /**
32  * @author http://www.cnblogs.com/initial-road/
33  * 大臣是天天要面见皇帝,今天见的皇帝和昨天的,前天不一样那就出问题了!
34  */
35 @SuppressWarnings("all")
36 public class Minister {
37
38     public static void main(String[] args) {
39         //第一天
40         Emperor emperor1 = Emperor.getInstance();
41         emperor1.emperorInfo();    //第一天见的皇帝叫什么名字呢?
42
43         //第二天
44         Emperor emperor2 = Emperor.getInstance();
45         emperor2.emperorInfo();
46
47         //第三天
48         Emperor emperor3 = Emperor.getInstance();
49         emperor3.emperorInfo();
50
51         //三天见的皇帝都是同一个人,荣幸吧!
52     }
53
54 }

  看到没,大臣天天见到的都是同一个皇帝,不会产生错乱情况,反正都是一个皇帝是好是坏就这一个,只要提到皇帝,大家都知道指的是谁,清晰,而又明确。
问题是这是通常情况,还有个例的,如同一个时期同一个朝代有两个皇帝,怎么办?

  单例模式很简单,就是在构造函数中多了加一个构造函数,访问权限是private的就可以了,这个模式是简单,但是简单中透着风险,风险?什么风险?在一个
B/S项目中,每个HTTP Request 请求到J2EE的容器上后都创建了一个线程,每个线程都要创建同一个单例对象,怎么办?好,我们写一个通用的单例程序,然后

分析一下:

 1 package com.iadmob.singleton;
 2
 3 /**
 4  * @author http://www.cnblogs.com/initial-road/
 5  * 通用的单例模式
 6  */
 7 public class SingletonPattern {
 8     private SingletonPattern singletonPattern = null;
 9
10     //限制住不能直接产生一个实例
11     private SingletonPattern(){
12
13     }
14
15     public SingletonPattern getInstance(){
16         if(this.singletonPattern == null){
17             this.singletonPattern = new SingletonPattern();
18         }
19         return this.singletonPattern;
20     }
21
22 }

  我们来看if条件那一部分,假如现在有两个线程A和线程B,线程A执行到this.singleton,Pattern = new SingletonPattern();正在申请内存分配,可能需要
0.001微妙,就在这0.001微妙之内,线程B执行到if(this.singletonPattern==null),你说这个时候这个判断条件是是true还是false?是true,那然后呢?

线程B也往下走,于是乎就在内存中就有两个Singleton的实例了,看看是不是出问题了?

  如果你这个单例是去那一个序号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性校验失败!最重要的是你从代码上还看不出什么问题,这
才是最要命的!因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?有很多种方案,我就说一种,能简单的、彻底解决问题的方案:

 1 package com.iadmob.singleton;
 2
 3 /**
 4  * @author http://www.cnblogs.com/initial-road/
 5  * 通用单例模式
 6  */
 7 public class SingletonPattern {
 8     private static final SingletonPattern singletonPattern = new SingletonPattern();
 9
10     //限制住不能直接产生一个实例
11     private SingletonPattern1(){
12     }
13
14     public synchronized static SingletonPattern getInstance(){
15         return singletonPattern;
16     }
17
18 }

  直接new一个对象传递给类的成员变量singletonpattern,你要的时候getInstance()直接返回给你,解决问题!

时间: 2024-12-22 13:11:05

24种设计模式--单例模式【Singleton Pattern】的相关文章

二十四种设计模式:单例模式(Singleton Pattern)

单例模式(Singleton Pattern) 介绍保证一个类仅有一个实例,并提供一个访问它的全局访问点. 示例保证一个类仅有一个实例. Singleton using System; using System.Collections.Generic; using System.Text; namespace Pattern.Singleton { /// <summary> /// 泛型实现单例模式 /// </summary> /// <typeparam name=&q

设计模式之单例模式Singleton pattern

单例模式Singleton pattern 一种软件设计模式.在核心结构中只包含一个被称为单例的特殊类. 一个类只有一个对象实例,并且自行实例化向整个系统提供. 动机 一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务:一个系统只能有一个窗口管理器或文件系统:一个系统只能有一个计时工具或ID(序号)生成器.如在Windows中就只能打开一个任务管理器.如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源:如果这些窗口显示的内容不

[设计模式](转)Java中的24种设计模式与7大原则

*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; text-decoration: none; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: poin

My study notes —— 初始24种设计模式

摘要 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 目录 设计概念 设计原则 四要素 基本模式 创建型 结构型 行为型 正文 设计概念 Change:让代码富有弹性,能够应对需求的变化: DRY:消除冗余,让代码更精炼: KISS:让代码

24种设计模式及七大设计原则

设计模式 七大设计原则 : 单一职责原则:            Single Responsibility Principle                一个类只负责一项职责    SRP 里氏替换原则:            Liskov Substitution Principle                   所有引用基类的地方,必须能透明地使用其子类的对象    LSP 依赖倒置原则:            Dependence Inversion Principle   

php设计模式——单例模式(Singleton)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 谷歌的Android设备 华为的Android设备 IOS只属于苹果公司 IOS只属于苹果公司 1 <?php 2 3 /* 4 * php

Android设计模式——单例模式(Singleton)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 package com.example.main; 2 3 import android.app.Activity; 4 import

七大原则,24种设计模式

七大设计原则: 1.单一职责原则[SINGLE RESPONSIBILITY PRINCIPLE]:一个类负责一项职责. 2.里氏替换原则[LISKOV SUBSTITUTION PRINCIPLE]:继承与派生的规则.(子类可替换父类) 3.依赖倒转原则[DEPENDENCE INVERSION PRINCIPLE]:高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象.即针对接口编程,不要针对实现编程. 4.接口隔离原则[INTERFACE SEGREGAT

Python七大原则,24种设计模式

七大设计原则:1.单一职责原则[SINGLE RESPONSIBILITY PRINCIPLE]:一个类负责一项职责.2.里氏替换原则[LISKOV SUBSTITUTION PRINCIPLE]:继承与派生的规则.(子类可替换父类)3.依赖倒转原则[DEPENDENCE INVERSION PRINCIPLE]:高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象.即针对接口编程,不要针对实现编程.4.接口隔离原则[INTERFACE SEGREGATION