Dev Zone
          偏執(zhí)狂才能生存,人生/事業(yè)的路上需要再堅持一下
          但是又怎么說得清堅持的結(jié)果,道得盡堅持的含義
          Ofbiz2.1有兩個bug,都涉及到線程安全性,小并發(fā)的時候不容易發(fā)現(xiàn),大并發(fā)下有時候會出現(xiàn),并發(fā)數(shù)越高出現(xiàn)的頻度就比較高,尤其對于實體引擎的那個bug,在系統(tǒng)初始化的時候如果遭遇大并發(fā),會有一定頻度的出現(xiàn)。
           
          1。entity engine的ModelEntity.getField方法存在線程安全隱患,會造成 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方法沒有同步(會造成性能下降),因此紅色標(biāo)標(biāo)注的那段代碼存在線程安全問題,必須進(jìn)行同步。在大并發(fā)下如果多個調(diào)用這個方法,最先調(diào)用的線程沒有執(zhí)行完循環(huán)的情況下,后續(xù)的線程通過最后的語句return的時候得到的就是Null(fieldsMap已經(jīng)被第一個線程賦值了,后續(xù)線程不會進(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);
                       }
              }
           
          這個Bug在3.0中已經(jīng)被修正。
           
          2。UtilCache.get方法同樣存在線程安全隱患,會造成LinkedList.remove或者LinedList.addFirst的空值針異常,不注意還會以為是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();
              }

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

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


          網(wǎng)站導(dǎo)航:
           
           
          主站蜘蛛池模板: 兴仁县| 明溪县| 大竹县| 梅州市| 通海县| 镇雄县| 安义县| 固安县| 廉江市| 蓝田县| 旌德县| 赤水市| 白城市| 永安市| 蕉岭县| 牟定县| 宣威市| 渭源县| 疏勒县| 阜新市| 辽宁省| 巩义市| 蓬安县| 南宁市| 霍邱县| 长沙市| 石狮市| 巴林左旗| 万荣县| 库车县| 铜梁县| 金湖县| 汉沽区| 汝城县| 固镇县| 望谟县| 油尖旺区| 同心县| 九江县| 桑日县| 阿克苏市|