这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此的广泛,如此的有人缘,单例就是单一、独苗的意思,那什么是独一份呢?你的思维是独一份,除此之外还有什么不能山寨的呢?我们举个比较难复制的对象:皇帝
中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝应该和昨天、前天的一样(过渡期的不考虑,别找茬哦),大臣磕完头,抬头一看,嗨,还是昨天那个皇帝,单例模式,绝对的单例模式,先看类图:
然后我们看程序实现,先定一个皇帝:
package com.cbf4life.singleton1;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 中国的历史上一般都是一个朝代一个皇帝,有两个皇帝的话,必然要PK出一个皇帝出来
*/
public class Emperor {
private static Emperor emperor = null; //定义一个皇帝放在那里,然后给这个皇帝名字
private Emperor(){
//世俗和道德约束你,目的就是不让你产生第二个皇帝
}
public static Emperor getInstance(){
if(emperor == null){ //如果皇帝还没有定义,那就定一个
emperor = new Emperor();
}
return emperor;
}
//皇帝叫什么名字呀
public static void emperorInfo(){
System.out.println("我就是皇帝某某某....");
}
}
然后定义大臣:
package com.cbf4life.singleton1;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 大臣是天天要面见皇帝,今天见的皇帝和昨天的,前天不一样那就出问题了!
*/
@SuppressWarnings("all")
public class Minister {
/**
* @param args
*/
public static void main(String[] args) {
//第一天
Emperor emperor1=Emperor.getInstance();
emperor1.emperorInfo(); //第一天见的皇帝叫什么名字呢?
//第二天
Emperor emperor2=Emperor.getInstance();
Emperor.emperorInfo();
//第三天
Emperor emperor3=Emperor.getInstance();
emperor2.emperorInfo();
//三天见的皇帝都是同一个人,荣幸吧!
}
}
看到没,大臣天天见到的都是同一个皇帝,不会产生错乱情况,反正都是一个皇帝,是好是坏就这一个,只要提到皇帝,大家都知道指的是谁,清晰,而又明确。问题是这是通常情况,还有个例的,如同一个时期同一个朝代有两个皇帝,怎么办?
单例模式很简单,就是在构造函数中多了加一个构造函数,访问权限是private的就可以了,这个模式是简单,但是简单中透着风险,风险?什么风险?在一个B/S项目中,每个HTTP Request请求到J2EE的容器上后都创建了一个线程,每个线程都要创建同一个单例对象,怎么办?,好,我们写一个通用的单例程序,然后分析一下:
package com.cbf4life.singleton3;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 通用单例模式
*/
@SuppressWarnings("all")
public class SingletonPattern {
private static SingletonPattern singletonPattern= null;
//限制住不能直接产生一个实例
private SingletonPattern(){
}
public SingletonPattern getInstance(){
if(this.singletonPattern == null){ //如果还没有实例,则创建一个
this.singletonPattern = new SingletonPattern();
}
return this.singletonPattern;
}
}
我们来看黄色的那一部分,假如现在有两个线程A和线程B,线程A执行到 this.singletonPattern = new SingletonPattern(),正在申请内存分配,可能需要0.001微秒,就在这0.001微秒之内,线程B执行到if(this.singletonPattern == null),你说这个时候这个判断条件是true还是false?是true,那然后呢?线程B也往下走,于是乎就在内存中就有两个SingletonPattern的实例了,看看是不是出问题了?
如果你这个单例是去拿一个序列号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性校验失败!最重要的是你从代码上还看不出什么问题,这才是最要命的!因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?有很多种方案,我就说一种,能简单的、彻底解决问题的方案:
package com.cbf4life.singleton3;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 通用单例模式
*/
@SuppressWarnings("all")
public class SingletonPattern {
private static final SingletonPattern singletonPattern= new SingletonPattern();
//限制住不能直接产生一个实例
private SingletonPattern(){
}
public synchronized static SingletonPattern getInstance(){
return singletonPattern;
}
}
直接new一个对象传递给类的成员变量singletonpattern,你要的时候getInstance()直接返回给你,解决问题!
补充说明:多线程调用时。有两种解决办法,第一种调用getInstance()方法的之前就初始好单态对象。这样多线程访问时不会造成影响。只是读取的时候不会造成影响,如果多个线程同时调用来进行修改删除的操作时就会出现问题。需要加上同步关键字synchronized。
第二种方法,在调用getInstance()方法过程种初始化单态对象。这样就需要进行条件判断,如果对象为空的话那么给对象创建对象。如果非空则不创建。
分享到:
相关推荐
单态模式(Singleton Pattern)是软件设计模式中的一种,它保证了类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如配置管理、线程池、缓存管理和日志记录等,因为它可以确保在整个系统中...
单态模式(Singleton Pattern)是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在.NET环境中,无论是C#还是ASP.NET项目,单态模式都是经常被用到的设计模式之一,尤其在处理全局配置、...
单态模式(Singleton Pattern)是设计模式中的一种,它的核心思想是限制类的实例化,确保一个类只有一个实例,并提供全局访问点。在.NET开发中,单态模式被广泛应用于那些需要频繁实例化然后销毁的对象,或者需要...
单态模式(Singleton Pattern)是设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这个模式通常用于控制资源的共享,比如数据库连接、线程池或者配置对象等。在Java或其他面向对象...
单态模式(Singleton Pattern)是设计模式中的一种基础模式,主要用来确保一个类只有一个实例,并提供一个全局访问点。在软件工程中,当一个类只能有一个实例而且客户可以从一个众所周知的访问点访问它时,这样的...
单态模式(Singleton Pattern)是设计模式中的一种,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。在MFC(Microsoft Foundation Classes)框架中,单态模式的应用同样重要,尤其对于需要全局共享的...
单态模式(Singleton Pattern)是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在需要频繁创建和销毁对象,且只允许存在一个实例的情况下非常有用,例如配置管理、线程池、缓存...
Java高级教程中的第六章主要讲解了五个常用的设计模式:单态模式、MVC模式、简单工厂模式、门面模式和适配器模式。设计模式是软件工程中经过实践验证的解决常见问题的有效策略,旨在提高代码的可复用性和可维护性。 ...
设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. ...
单态模式(Singleton Pattern)是软件设计模式中最基础且常用的一种模式,主要目的是控制类的实例化过程,确保一个类在整个应用程序中只有一个实例,并提供一个全局访问点。这个模式在Java编程中尤其常见,因为Java...
1. **单态模式(Singleton Pattern)**: - 单态模式是一种设计模式,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点。在Java中,通常通过以下两种方式实现单态模式: - **饿汉式(Eager ...