2014-10-17 47 views
0

我正在實現this postother post中描述的非確定性有限自動機,使用Konrad Rudolph's proposed algorithm帶有HashSet的java.util.ConcurrentModificationException

而不是使用C++ multimap,我使用了一個HashSet<Character> [][] transitions數組(這是作業和谷歌的番石榴庫不能使用)。第一維是原點狀態,第二維是命運狀態,HashSet定義了原點和命運狀態之間轉換的符號。我的自動機類的構造函數是:

Automaton (int numberOfStates) 
{ 
    this.numberOfStates = numberOfStates; 
    alphabet = new HashSet<>(); 
    finalStates = new HashSet<>(); 

    transitions = new HashSet[numberOfStates][numberOfStates]; 

    for (int i = 0; i < numberOfStates; i++) 
    { 
     for (int j = 0; j < numberOfStates; j++) 
     { 
      transitions[i][j] = new HashSet<Character>(); 
     } 
    } 
} 

這是使用這種轉換陣列我實現康拉德·魯道夫的算法:

public String readStringInAutomaton (char[] inputString, 
      int initialState) 
{ 
    HashSet<Integer> currentStates = new HashSet<>(); 
    HashSet<Integer> nextStates = new HashSet<>(); 

    currentStates.add(initialState); 

    // for each char in inputString 
    for (int charIndex = 0; charIndex < inputString.length; charIndex++) 
    { 
     char currentTransitionChar = inputString[charIndex]; 
     // for each state in currentStates 
     for (Integer originState : currentStates) 
     { 
      // for each transition starting from originState, current 
      // char 
      for (int destinyStateIndex = 0; destinyStateIndex < numberOfStates; destinyStateIndex++) 
      { 
       if (transitions[originState][destinyStateIndex] 
         .contains(currentTransitionChar)) 
       { 
        nextStates.add(destinyStateIndex); 
       } 
      } 
     } 
     currentStates = nextStates; 
    } 
} 

我試着Collections.synchronizedSet(new HashSet<>());更換HashSet中的每一個實例,如推薦Oracle's HashSet documentation

但是,當初始化轉換時,我得到一個java.lang.ArrayStoreException:java.util.Collections $ SynchronizedSet。

for (int i = 0; i < numberOfStates; i++) 
{ 
    for (int j = 0; j < numberOfStates; j++) 
    { 
     transitions[i][j] = Collections 
       .synchronizedSet(new HashSet<>()); 
    } 
} 

如何避免這些併發異常?

+0

請提供完整的代碼示例,說明您遇到的具體問題。確保包含堆棧跟蹤並顯示哪一行導致異常。 – 2014-10-17 19:37:19

+0

請注意,在這種情況下'ConcurrentModificationException'有**沒有任何**與多線程處理,因爲這裏沒有多個線程。 – 2014-10-17 19:46:14

回答

5

你的問題不是關於多線程,而是關於你在不斷添加元素的Set迭代。

你有currentStates = nextStates,然後在你的for循環for (Integer originState: currentStates)你做nextStates.add(destinyStateIndex)無需重新分配nextStates(而nextStatescurrentStates被actualling相同的實例!)。

你應該改正你的算法:nextStates必須根據你使用它的方式在循環的某個地方重新分配。