單例模式的思想簡介

單例的基本思惟html

單例是一種保證對象只有一個的設計模式。java

好比數據庫鏈接。若是用hibernate,會在應用初始化時,就建立數據庫鏈接。在訪問時經過方法,而不是經過new產生。web

對比其餘的幾種作法:sql

1在須要時new鏈接對象,用完後關閉。這樣頻繁的開和關,效率低。同時代碼融入不少無關的成分。數據庫

2在初始化時new,放到全局區,好比java web的application context中。這種訪問太直接了。設計模式

 

單例的經典實現(代碼)緩存

 

單例的基本實現

也能夠參考這篇文章session

http://www.cnblogs.com/BoyXiao/archive/2010/05/07/1729376.html?login=1多線程

 

單例的本質app

1單例是一種保證對象只有一個的設計模式。

2單例的本質在於共享

1並無說明何時該用單例模式,而2則是針對這點的。

共享有兩種狀況:

因爲使用共享的資源(如static,文件等),不得不禁共享對象來操做。

某對象比較複雜,不該該每一個使用者都建立一個,因此共享。

3單例和全局變量

從使用角度來講,單例和全局變量都是爲了共享。但惟有單例才能保證對象只有一個,因此單例和全局變量有所不一樣。

但有時單例不必定用getInstance的方法實現的。好比說Spring中也把動態生成的對象叫單例,這種單例並無用單例模式約束的,僅僅就是用戶不本身建立,而是使用Spring提供的那個對象(本質上是放在session的全局變量,但也有人叫這種對象單例)

4單例不必定是隻有一個的

       好比qq軟件的登陸狀態對象,咱們但願每一個用戶在某一時刻只有一個登陸狀態對象,不能夠在兩臺機子同時上q。那麼在服務端就會爲每一個用戶的登陸狀態創建一個單例。好比

View Code

單例的重要概念

1單例的生存週期。單例何時會銷燬。有的是request級的,有的是session級的,有的是application級的。這主要看單例依賴於什麼。好比登陸信息放在session中,就會是session基本的。單例經常用static實現,因爲static屬於類成員,只有在應用中止時纔會銷燬,因此是application級別的。

2單例與多線程。既然單例共享資源,就必定要考慮多線程問題。對操做共享資源的函數,就要加同步了。百聞不如一見,仍是貼一段代碼,代碼的背景是這樣的,數據庫中存了樹形結構的數據,這個類RoleTree把樹結構讀出來,緩存到static中。做爲一個單例給須要使用這顆樹的地方調用。

  1 package com.xcat.user;
  2 
  3 import java.sql.Connection;
  4 import java.sql.PreparedStatement;
  5 import java.sql.SQLException;
  6 import java.util.ArrayList;
  7 import java.util.HashMap;
  8 import java.util.HashSet;
  9 import java.util.LinkedList;
 10 import java.util.List;
 11 import java.util.Map;
 12 import java.util.Queue;
 13 import java.util.Set;
 14 
 15 import com.xcat.common.DB;
 16 
 17 public class RoleTree {
 18     private Map<Integer,Role> treeUp;
 19     private Map<Integer,Set<Integer>> treeDown;
 20     private static RoleTree instance = null;
 21     private RoleDao roleDao;
 22     
 23     private RoleTree() {
 24         roleDao = new RoleDao();
 25         reinit(roleDao.list());
 26     }
 27     
 28     public static synchronized RoleTree getInstance() {   
 29         if (instance == null) {   
 30             instance = new RoleTree(); 
 31         }
 32         return instance;
 33     }  
 34     
 35     public void reinit(List<Role> ls){
 36         
 37         treeUp = new HashMap<Integer,Role>();
 38         treeDown = new HashMap<Integer,Set<Integer>>();
 39         for(Role r : ls){
 40             treeUp.put(r.getId(), r);
 41             treeDown.put(r.getId(), new HashSet<Integer>());
 42         }
 43         treeDown.put(0,new HashSet<Integer>());
 44         for(Role r : ls){
 45             treeDown.get(r.getParentId()).add(r.getId());
 46         }
 47     }
 48     
 49     public synchronized void add(Role r){
 50         roleDao.add(r); 
 51         r= roleDao.loadByName(r.getName());
 52         treeUp.put(r.getId(), r);
 53         treeDown.put(r.getId(), new HashSet<Integer>());
 54         treeDown.get(r.getParentId()).add(r.getId());
 55         
 56     }
 57     
 58     public void addAsRoot(Role r){
 59         r.setParentId(0);
 60         add(r);    
 61     }
 62     
 63     public void addByParent(Role r,int parentId){
 64         r.setParentId(parentId);
 65         add(r);
 66     }
 67     
 68     public List<Role> getChildren(int id){
 69         List<Role> ls= new ArrayList<Role>();
 70         Queue<Integer> queue = new LinkedList<Integer>();
 71         queue.offer(id);
 72         while (queue.peek()!=null){
 73             int cur=queue.poll();
 74             ls.add(treeUp.get(cur));
 75             Set<Integer> set=treeDown.get(cur);
 76             if(set!=null)
 77                 for(int i : set) queue.offer(i);
 78         }
 79         
 80         for(Role r : ls) 
 81             if(r.getId()==0) {
 82                 ls.remove(r);
 83                 break;
 84             }
 85         
 86         return ls;
 87     }
 88     
 89     public List<Role> list(){
 90         List<Role> ls= new ArrayList<Role>();
 91         for(Role r : treeUp.values()){
 92             ls.add(r);
 93         }
 94         
 95         for(Role r : ls) 
 96             if(r.getId()==0) {
 97                 ls.remove(r);
 98                 break;
 99             }
100         
101         return ls;
102     }
103     
104     public Role loadById(int id) {
105         Role r;
106         if(treeUp.containsKey(id)) r=treeUp.get(id);
107         else r=null;
108         return r;
109     }
110     
111     public List<Object[]> getIndentName(){
112         List<Object[]> ls= new ArrayList<Object[]>();
113         for(int i : treeDown.get(0)) _getInent(ls,i,0);
114         return ls;
115     }
116     
117     private void _getInent(List<Object[]> ls, int cur ,int level){
118         
119         Object[] objs =new Object[2];
120         objs[0]=treeUp.get(cur).getId();
121         String name="";
122         for(int i=0;i<level;i++) name+="-";
123         objs[1]=name+treeUp.get(cur).getName();
124         ls.add(objs);
125         
126         for(int i : treeDown.get(cur))
127             _getInent(ls,i,level+1);
128     }
129     
130     private void showTreeDown(){
131         for(int key : treeDown.keySet()) {
132             for(int i : treeDown.get(key)) System.out.print(i+",");
133             System.out.println("");
134         }
135     }
136     
137     public synchronized  void update(Role r) {
138         roleDao.update(r);
139         
140         int oldId=treeUp.get(r.getId()).getParentId();
141         treeDown.get(oldId).remove(r.getId());
142         treeUp.remove(r.getId());
143         
144         treeUp.put(r.getId(), r);
145         treeDown.get(r.getParentId()).add(r.getId());
146     }
147     
148     public synchronized void updateParent(int id , int parentId) {
149         roleDao.updateParent(id, parentId);
150         
151         int oldId=treeUp.get(id).getParentId();
152         treeDown.get(oldId).remove(id);
153         
154         treeUp.get(id).setParentId(parentId);
155         treeDown.get(parentId).add(id);
156     }
157     
158     public void delete(Role r) {
159         deleteById(r.getId());
160     }
161     
162     public synchronized boolean deleteById(int id) {
163         if(treeDown.get(id).size()!=0) return false;
164         
165         roleDao.deleteById(id);
166         
167         int oldId=treeUp.get(id).getParentId();
168         treeUp.remove(id);
169         treeDown.get(oldId).remove(id);
170         treeDown.remove(id);
171         return true;
172     }
173     
174     public synchronized void deleteBranch(int id) {
175         List<Role> ls=getChildren(id);
176         System.out.println("size:"+ls.size());
177         List<Integer> lsi=new ArrayList<Integer>();
178         for(Role r : ls) lsi.add(r.getId());
179         roleDao.deletebyIds(lsi);
180         
181         reinit(roleDao.list());
182     }
183 }
單例與多線程示例

類關係(類圖)

 

 

參考文章:http://blog.csdn.net/hguisu/article/details/7515416

相關文章
相關標籤/搜索