当前位置: 首页 > 图灵资讯 > 技术篇> 《设计模式之禅》Singleton_Pattern--单例模式

《设计模式之禅》Singleton_Pattern--单例模式

来源:图灵教育
时间:2023-05-25 09:12:43

单例模式

这种模式非常有趣,非常有趣,相对简单,但我仍然想说,因为它被广泛使用,如此受欢迎,单一的例子意味着单一,单一的幼苗,那么什么是独一无二的呢?你的想法是独一无二的,还有什么不能模仿的呢?让我们举一个更难复制的对象:皇帝(那个天子)

在中国历史上,两位皇帝并存的时期很少,但很少(你可以想象瓦拉战神)。然后我们认为皇帝是一个单一的例子模式。在这种情况下,有皇帝和大臣。大臣们每天都要去朝廷见皇帝。今天拜访的皇帝应该和昨天和前天一样(不要考虑过渡期,不要找错),大臣们敲了敲头,抬头一看,嗨,或者昨天的皇帝,单一的例子模式,绝对的单一的例子模式,先看类图:

《设计模式之禅》Singleton_Pattern--单例模式_构造器

实现程序定义一个皇帝
/** * @author LeeZhi * @version 1.0 */@SuppressWarnings({"all"})public class Emperor {    private static Emperor emperor = null; //定义一个皇帝放在那里,然后给皇帝起个名字    public Emperor() {        /世俗和道德约束,第二个皇帝不会产生{    }    public static Emperor getInstance(){        if (emperor==null){            //如果皇帝还定义,然后定义一个皇帝            emperor = new Emperor();            System.out.println(emperor);        }        return emperor;    }    public static void emperorInfo(){        System.out.println(”天大地大,皇权天赋,老子是天子,我是最大的,我是皇帝XXX”);    }}

通过无参构造器限制

定义静态方法,getinstance获取皇帝的实例对象。

定义大臣
/** * @author LeeZhi * @version 1.0 */@SuppressWarnings({"all"})public class Minister {    public static void main(String[] args) {        //第一天        Emperor emperor1 = Emperor.getInstance();        emperor1.emperorInfo();        //第二天        Emperor emperor2 = Emperor.getInstance();        emperor2.emperorInfo();        //第三天        Emperor emperor3 = Emperor.getInstance();        emperor3.emperorInfo();        //三天见的皇帝都是同一个人,荣幸吧!    }}

看,大臣们每天都看到同一个皇帝,不会有混乱,无论如何,是一个皇帝,是好是坏(不管他是坏),只要提到皇帝,每个人都知道谁,清楚,清楚。问题是,这是通常的情况,还有一个例子,就像同一个朝代有两个皇帝一样,该怎么办?瓦拉战神又来了

Attation

单例模式很简单,就是在构造函数中加一个构造函数,访问权限是private。这个模式很简单,但是简单中有风险和风险?什么风险?在B/S项目中,每个HTTP Request要求在J2EE容器上创建一个线程,每个线程创建相同的单例对象。我该怎么办?,好吧,我们写一个通用的单例程序,然后分析一下:

/** * @author LeeZhi * @version 1.0 * 一般单例模式 */@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;    }}

 

《设计模式之禅》Singleton_Pattern--单例模式_构造函数_02

让我们来看看黄色的部分。如果现在有两个线程A和线程B,线程A将执行到this.singletonPattern=new SingletonPattern (申请内存分配可能需要0.001微秒,在0.001微秒内,线程B执行到if(this.singletonPattern=null),你说这个时候的判断条件是true还是false?是true,那么呢?是true,那么呢?线程B也在下降,所以内存中有两个SingletonPattern的例子,看看有没有问题。如果你拿一个序列号或者创建一个信号资源,这个单例会怎么样?业务逻辑混乱!数据一致性验证失败!最重要的是,你在代码上看不到任何问题,这是最致命的!因为你基本上不能重现这种情况,不寒而栗,那怎么修改呢?有很多方案,我会说一个简单彻底的解决问题的方案:

修改后
/** * @author LeeZhi * @version 1.0 * 一般单例模式 */@SuppressWarnings("all")public class SingletonPattern {    private static SingletonPattern singletonPattern = new SingletonPattern();    ///无参构造器的限制不能直接生成一个例子    private SingletonPattern() {    }//    public SingletonPattern getInstance(){//        if(this.singletonPattern==null){ //如果没有实例,创建一个//////            this.singletonPattern = new SingletonPattern();//        }//        return this.singletonPattern;//    }        public synchronized SingletonPattern getInstance(){            return singletonPattern;    }}

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

说白了,在过程(或线程)中只能有一个实例对象,记得无参结构器要给私有权限。