zoukankan      html  css  js  c++  java
  • 单例模式的思想简介

    单例的基本思维

    单例是一种保证对象只有一个的设计模式。

    比如数据库连接。如果用hibernate,会在应用初始化时,就创建数据库连接。在访问时通过方法,而不是通过new产生。

    对比其他的几种做法:

    1在需要时new连接对象,用完后关闭。这样频繁的开和关,效率低。同时代码融入很多无关的成分。

    2在初始化时new,放到全局区,比如java web的application context中。这种访问太直接了。

    单例的经典实现(代码)

    单例的基本实现

    也可以参考这篇文章

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

    单例的本质

    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

  • 相关阅读:
    第十一周编程总结
    第十周编程总结
    第九周
    第八周
    第七周编程总结
    第六周编程总结
    学期总结
    第十四周课程总结&实验报告(简单记事本的实现)
    第十三周课程总结
    第十二周课程总结
  • 原文地址:https://www.cnblogs.com/deliver/p/4792322.html
Copyright © 2011-2022 走看看