Dev Zone
          偏執(zhí)狂才能生存,人生/事業(yè)的路上需要再堅(jiān)持一下
          但是又怎么說得清堅(jiān)持的結(jié)果,道得盡堅(jiān)持的含義
          Ofbiz2.1有兩個(gè)bug,都涉及到線程安全性,小并發(fā)的時(shí)候不容易發(fā)現(xiàn),大并發(fā)下有時(shí)候會(huì)出現(xiàn),并發(fā)數(shù)越高出現(xiàn)的頻度就比較高,尤其對(duì)于實(shí)體引擎的那個(gè)bug,在系統(tǒng)初始化的時(shí)候如果遭遇大并發(fā),會(huì)有一定頻度的出現(xiàn)。
           
          1。entity engine的ModelEntity.getField方法存在線程安全隱患,會(huì)造成 XXXX is not a field of XXX的異常,以下是原有代碼片斷:

              
          public ModelField getField(String fieldName) {
                  
          if (fieldName == nullreturn null;
                  if (fieldsMap == null) {
                      fieldsMap = new HashMap(fields.size());
                      for (int i = 0; i < fields.size(); i++) {
                          ModelField field = (ModelField) fields.get(i);
                          fieldsMap.put(field.name, field);
                  }
                  return (ModelField) fieldsMap.get(fieldName);
              }

          由于getField方法沒有同步(會(huì)造成性能下降),因此紅色標(biāo)標(biāo)注的那段代碼存在線程安全問題,必須進(jìn)行同步。在大并發(fā)下如果多個(gè)調(diào)用這個(gè)方法,最先調(diào)用的線程沒有執(zhí)行完循環(huán)的情況下,后續(xù)的線程通過最后的語句return的時(shí)候得到的就是Null(fieldsMap已經(jīng)被第一個(gè)線程賦值了,后續(xù)線程不會(huì)進(jìn)入紅色標(biāo)準(zhǔn)的代碼區(qū)域)。
          修改后的代碼如下:
             public ModelField getField(String fieldName) {
                  
          if (fieldName == nullreturn null;
                  
          if (fieldsMap == null) {
                       createFields();
                  }
                  
          return (ModelField) fieldsMap.get(fieldName);
              }

              
          public synchronized void createFields()
              {
                       fieldsMap 
          = new HashMap(fields.size());
           
                       
          for (int i = 0; i < fields.size(); i++) {
                           ModelField field 
          = (ModelField) fields.get(i);
           
                           fieldsMap.put(field.name, field);
                       }
              }
           
          這個(gè)Bug在3.0中已經(jīng)被修正。
           
          2。UtilCache.get方法同樣存在線程安全隱患,會(huì)造成LinkedList.remove或者LinedList.addFirst的空值針異常,不注意還會(huì)以為是LinkedList的bug。以下是原代碼片斷:
              public Object get(Object key) {
                  
          if (key == null) {
                      missCount
          ++;
                      
          return null;
                  }
                  UtilCache.CacheLine line 
          = (UtilCache.CacheLine) cacheLineTable.get(key);
                  
          if (hasExpired(line)) {
                      
          // note that print.info in debug.properties cannot be checked through UtilProperties here, it would cause infinite recursion
                      
          // if (Debug.infoOn()) Debug.logInfo("Element has expired with key " + key);
                      remove(key);
                      line 
          = null;
                  }
                  
          if (line == null) {
                      
          // if (Debug.infoOn()) Debug.logInfo("Element not found with key " + key);
                      missCount++;
                      
          return null;
                  }
                  
          // if (Debug.infoOn()) Debug.logInfo("Element found with key " + key);
                  hitCount++;
                  if (maxSize > 0) {
                      keyLRUList.remove(key);
                      keyLRUList.addFirst(key);
                  }

                  return line.getValue();
              }
          紅色標(biāo)準(zhǔn)的部分是有問題的代碼,修改后的代碼如下:
              public Object get(Object key) {
                  
          if (key == null) {
                      missCount
          ++;
                      
          return null;
                  }
                  UtilCache.CacheLine line 
          = (UtilCache.CacheLine) cacheLineTable.get(key);
                  
          if (hasExpired(line)) {
                      
          // note that print.info in debug.properties cannot be checked through UtilProperties here, it would cause infinite recursion
                      
          // if (Debug.infoOn()) Debug.logInfo("Element has expired with key " + key);
                      remove(key);
                      line 
          = null;
                  }
                  
          if (line == null) {
                      
          // if (Debug.infoOn()) Debug.logInfo("Element not found with key " + key);
                      missCount++;
                      
          return null;
                  }
                  
          // if (Debug.infoOn()) Debug.logInfo("Element found with key " + key);
                  hitCount++;
                  
          if (maxSize > 0) {
                      synchronized ( 
          this)
                      {
                           keyLRUList.remove(key);
                           keyLRUList.addFirst(key);
                      }
                  }
                  
          return line.getValue();
              }

          這個(gè)BUG在3.0種也修正了。
          posted on 2005-05-17 22:07 dev 閱讀(318) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
           
          主站蜘蛛池模板: 凤阳县| 崇州市| 西畴县| 比如县| 登封市| 和平县| 集贤县| 麟游县| 张掖市| 南京市| 营口市| 平谷区| 甘肃省| 泸溪县| 苏尼特左旗| 从化市| 安阳县| 忻州市| 洱源县| 浠水县| 苏尼特左旗| 新绛县| 屏山县| 呼和浩特市| 温泉县| 临海市| 兴义市| 靖州| 岳阳县| 喀喇沁旗| 芒康县| 黔西| 虎林市| 丽水市| 团风县| 武宣县| 应城市| 望城县| 徐闻县| 郓城县| 双城市|