单例模式是一种在项目中经常会用到并且很有用的模式,同样也非常简单。
Singleton_Pattern(单例模式)
ChairMan类:
class="java">package com.dsl.singleton_pattern; /** * 一个国家只能有一个ChairMan或一个Premier吧! * @author EX-DENGSHENGLONG217 * */ public class ChairMan { private static ChairMan chairMan=null;//声明一个ChairMan放在这里 private ChairMan(){ //什么是单例:说的简单点就是你不能new出来,不能创建多个实例,所以我们就private它的构造器 } //总得提供一个获得他的方法吧 public static ChairMan getInstance(){ if(chairMan==null){ chairMan=new ChairMan(); } return chairMan; } //ChairMan相关信息 public static void getChairManInfo(){ System.out.println("我是中国人民共和国国家ChairMan:习总!"); } //这样一个简单的单例模式就出来了 }
?
people类:
package com.dsl.singleton_pattern; public class People { /** * 定义老百姓:他们每天面对的只有一个ChairMan * @param args */ @SuppressWarnings("all") public static void main(String[] args) { ChairMan cm1=ChairMan.getInstance(); cm1.getChairManInfo(); ChairMan cm2=ChairMan.getInstance(); cm2.getChairManInfo(); //看起来是好像有两个ChairMan了,但是他们的信息都是一样的,还是同一个ChairMan //认真观察下面打印出来的你会发现两个对象在内存中的地址是一样的 boolean flag=cm1.equals(cm2); System.out.println(cm1+"\t"+cm2+"\t"+flag); } }
?
Please read below Info,MayBe is important for you.
??? 其实像ChairMan这样简单的单例模式却存在着巨大的风险:我们来作一些简单的分析,如果现在有A和B两个线程,当A线程执行到if(chairMan==null)时发现这里为true所以
继续,所花时间假如为0.0001us,可就在这个时间段里B线程也执行到了if(chairMan==null)这里,那这时候怎么办?很显然这里也为true,因此B线程也会继续下去,这样造成
的结果就是在内存中存在了两个ChairMan对象,那这还叫什么单例,如果你这个单例是去拿一个序列号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性
校验失败!最重要的是你从代码上还看不出什么问题,这才是最要命的!因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?下面提供一种简单的修改方式:
修改后的单例(Singleton类)
package com.dsl.singleton_pattern; /** * 通用单例不会存在同步问题 * @author EX-DENGSHENGLONG217 * */ public class Singleton { private static final Singleton singleton=new Singleton();//直接new一个出来并声明为static final private Singleton(){//限制new出来 } public synchronized static Singleton getInstance(){ return singleton; } }
?