單例模式(SingLeton Pattern)的誤區
今天一個朋友問過這樣一個問題:為什么他的單例每次都進入構造函數,程序如下:
?????private?static?ServerThread?instance?=?null;??
?????private?ServerThread()?{
?????????try?{
?????????????if?(socket?==?null)?{
?????????????????socket?=?new?DatagramSocket(Constants.SERVER_PORT);
?????????????}
??????????}?catch?(Exception?e)?{
?????????????????e.printStackTrace();
???????????}
???????}
?????public?static?final?ServerThread?getInstance()?{
????????if?(instance?==?null)?{
???????????System.out.println("instance?is?null?new?generate
.");
???????????instance?=?new?ServerThread();
????????}
????????return?instance;
??????}
????public?Thread?getThreadInstance()?{
????????if?(threadInstance?==?null)?{
????????????threadInstance?=?new?Thread(instance);
????????}
????????return?threadInstance;
????}
。。。。。。。。
}
??????main函數有servTr?=?ServerThread.getInstance().getThreadInstance();一句
代碼沒有問題吧;為什么他的單例每次都進入構造函數呢?
細問之下才知道了他啟動了兩次Main類;啟動一個Main類便在一個JVM,兩次的單例怎么能是同一個呢?!
記住:是在同一個JVM中唯一,不是在一個物理內存中唯一。當然后者不是不能做到的,分布式對象嘛,呵呵。
第二點就是:單例的構造:
目前方式多種,我認為只有兩種是正確的:
第一:private final static DaoFactory instance = new DaoFactory();
第二:
??????private?Properties?props?=?null;
???????private?Map?daos?=?null;
??????private?DaoFactory()?{
???????????props?=?new?Properties();
???????????daos?=?new?HashMap();
??????}
?????
??????public?static?DaoFactory?getInstance()?{
???????????while?(null?==?instance)?{
?????????????????synchronized(DaoFactory.class)?{
??????????????????????if?(null?==?instance)?{
????????????????????????????instance?=?new?DaoFactory();
????????????????????????????instance.initDaoFactroy();
??????????????????????}
?????????????????}
???????????}
???????????return?instance;
??????}
看清楚了,這里用的是while;不是if。
為什么不能用if呢?下面的一個例子說明
??????private?List?provinces;
?
???????????private?Map?domains;
??????private?static?DomainFactory?instance;
??????private?DomainFactory()?{
???????????generateDomainTree();
??????}
??????public?static?DomainFactory?getInstance()?{
???????????if?(null?==?instance)?{
?????????????????synchronized?(DomainFactory.class)?{
??????????????????????if?(null?==?instance)?{
????????????????????????????instance?=?new?DomainFactory();
??????????????????????}
?????????????????}
???????????}
???????????return?instance;
??????}
??????private?void?generateDomainTree()?{
。。。。。
}
??????private?Map?map;?????
??????private?static?CategoryFactory?instance;
?????
??????private?CategoryFactory()?{
???????????map?=?new?HashMap();
???????????generateCategoryTree();
??????}?????
??????public?static?CategoryFactory?getInstance()?{
???????????if?(null?==?instance)?{
?????????????????synchronized?(CategoryFactory.class)?{
??????????????????????if?(null?==?instance)?{
????????????????????????????instance?=?new?CategoryFactory();
??????????????????????}
?????????????????}
???????????}
???????????return?instance;
??????}?????
??????private?void?generateCategoryTree()?{
。。。。。。
}
?
??????public?ActionForward?getCatalogData(ActionMapping?mapping,?ActionForm?form,
?????????????????HttpServletRequest?request,?HttpServletResponse?response)?{
???????????DomainObject?domainObject?=?new?DomainObject();
???????????domainObject.setCity("b");
???????????request.getSession().setAttribute("domainObject",?domainObject);
???????????request.setAttribute("domains",?DomainFactory.getInstance().getCity(domainObject.getCity()));
???????????return?mapping.findForward("left");
??????}????
?
??????public?ActionForward?getCatalogDataCategory(ActionMapping?mapping,?ActionForm?form,
?????????????????HttpServletRequest?request,?HttpServletResponse?response)?{
???????????request.setAttribute("productCategories",?CategoryFactory.getInstance().getRootProductCategories());
???????????return?mapping.findForward("body");
??????}
????<frame?name="header"?src="./search_header.jsp"?scrolling="no"?title="header"?noresize="noresize">
????<frameset?cols="180,*"?frameborder="yes"?border="0"?framespacing="0">
???????<frame?name="left"?scrolling="no"?src="search.html?method=getCatalogData"?target="_self"?noresize="noresize">
???????<frame?name="body"?scrolling="yes"?src="search.html?method=getCatalogDataCategory"?scrolling="yes"?target="_self"?noresize="noresize">
??</frameset>
</frameset>
posted on 2006-07-15 00:02 crazycy 閱讀(2539) 評論(13) 編輯 收藏 所屬分類: Design Pattern、JEE Pattern