单例模式
这种模式非常有趣,非常有趣,相对简单,但我仍然想说,因为它被广泛使用,如此受欢迎,单一的例子意味着单一,单一的幼苗,那么什么是独一无二的呢?你的想法是独一无二的,还有什么不能模仿的呢?让我们举一个更难复制的对象:皇帝(那个天子)
在中国历史上,两位皇帝并存的时期很少,但很少(你可以想象瓦拉战神)。然后我们认为皇帝是一个单一的例子模式。在这种情况下,有皇帝和大臣。大臣们每天都要去朝廷见皇帝。今天拜访的皇帝应该和昨天和前天一样(不要考虑过渡期,不要找错),大臣们敲了敲头,抬头一看,嗨,或者昨天的皇帝,单一的例子模式,绝对的单一的例子模式,先看类图:
实现程序定义一个皇帝
/** * @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; }}
让我们来看看黄色的部分。如果现在有两个线程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,想要的时候直接返回给你解决问题!
说白了,在过程(或线程)中只能有一个实例对象,记得无参结构器要给私有权限。