一个类A中有一个静态变量和几个访问该变量的静态方法,代码如下:
public class MonitorParaMap {
private static HashMap paraMap = new HashMap();
public static void put(Object key,Object value){
paraMap.put(key,value);
}
public static Object get(Object key){
return paraMap.get(key);
}
public static HashMap getMap(){
return paraMap;
}
}
我在Action,service和dao中分别用到put方法把不同的key-value对put到HashMap中,而且可能会有多个线程同时运行,请问怎样才能保证一个线程从action开始到dao结束时没有别的线程访问那个静态的HashMap

解决方案 »

  1.   

    你如果只是想在整个应用中只有一个hashmap存储数据,我建议你使用singleton模式,而不是使用static方法,因为static方法类似全局方法,而且也不能使用sychronized(如果我没有记错的话),使用singleton的话,可以象下面这样:
    public class MonitorParaMap {
        private HashMap paraMap = ...;
        private static MonitorParaMap monitor = ...;
        private MonitorParaMap() {
        }
        
        public static MonitorParaMap getInstance() {
            if(monitor == null) {
              monitor = ...;
            }
            return monitor;
        }     public sychronized void put(...) {
            ...;
        }
        public sychronized Object get(Object key) {
           ...;
        }    public sychronized HashMap getMap() {
           ...; 
        }
    }
      

  2.   

    建议用 Hashtable
    import java.util.Hashtable;class MonitorParaMap {  private static Hashtable paraMap = new Hashtable();  public static synchronized void put(Object key, Object value) {
        paraMap.put(key, value);
      }  public static synchronized Object get(Object key) {
        return paraMap.get(key);
      }  public static Hashtable getMap() { // 
        return paraMap;
      }
    }
    如果只是想达到唯一使用 HashMap 的话,可以简单的用
    public class MonitorParaMap {
      public static Object lock = new Object(); // 增加这个锁
     .. // 其他的用你原有的就可以
    }在你的代码里面,有并发访问HashMap的地方使用
    synchronized(MonitorParaMap.lock){
      .....
    }
      

  3.   

    1楼的方法似乎并没有实现楼主的要求吧。
    楼主的要求是一次请求从action到dao结束都要排他。如果只是这几个方法声明为sychronized,那么对象锁只是在这几个方法被调用的时候被该线程保存了。java2000_net,用HashTable有什么特别的好处吗?
      

  4.   

    对,我说的就是红魔菜的意思,Hashtable是线程安全的,不过好像也不能实现我的要求吧,他只是在一个类中安全,但在一个流程中应该不行吧,怎么对这个流程就行同步呢(赫赫,这样好像就不是多线程了)
      

  5.   

    > 1楼的方法似乎并没有实现楼主的要求吧。 
    > 楼主的要求是一次请求从action到dao结束都要排他。如果只是这几个方法声明
    > 为sychronized,那么对象锁只是在这几个方法被调用的时候被该线程保存了。 我觉得要在这么长的时间里保持排他,恐怕设计上有问题,当请求比较密集的时候会出现无谓的等待。实现起来应该不是什么大问题,搞个标志变量应该就可以了。但我觉得还是得从设计上重新考虑一下,不要“独占”得那么奢侈。
      

  6.   

    Hashtable 至少能保证,我在内部处理的时候不会发生冲突。而多线程共享,建议用我提供的第二种方法,用共享锁解决。只有一个线程能拿到那个锁,也就只有他能存取HashMap 了。。
    记住,你所有的对HashMap的外部访问,必须放在这个synchronized(MonitorParaMap.lock) 里面,否则没意义。
      

  7.   

    一次请求从头到尾不可能只有一段代码,用synchronized(MonitorParaMap.lock)的话,可能还是会有并发访问。
    如果楼主一定要这样设计的话,可以考虑maquan说的标识变量的方法。
    设置一个volatile的标记变量,访问这个全局的map前先判断该标记就是了。