2011-04-26 71 views
2

可能重複:
Thread safety in Singleton線程安全的單

喜,

我使用網詞典找到單詞的同義詞。由於我有很多文檔,我使用多個線程來執行文檔預處理,其中涉及詞幹,停用詞和同義詞替換。

我正在使用以下代碼來訪問字典並獲取每個文檔的字集。

IndexWordSet set = Dictionary.getInstance().lookupAllIndexWords(newWord); 

這在單線程環境中正常工作。但是在多線程環境中,這並沒有像預期的那樣工作。程序在一段時間後卡住了。

這是因爲Dictionary.getInstance()是單例類,它不是線程安全的?如果是這樣,我怎樣才能修改字典的訪問權限,以便它是線程安全的? (我不能修改字典類,因爲我用的字典庫)

+0

將使用字典作爲單身人士的類會幫助嗎? – 2011-04-26 04:26:05

+0

你將不得不諮詢他的wordnet詞典API,看看它是否是線程安全的。 – MeBigFatGuy 2011-04-26 04:27:20

+0

如果您確定此代碼不是線程安全的,則必須在所有訪問器使用的同步塊中進行此調用。 'synchronized(someLockingObject){return Dictionary.getInstance()。lookupAllIndexWords(newWord); }' – MeBigFatGuy 2011-04-26 04:28:53

回答

0

可以使用​​之一...

或者你可以在單一實例中使用同步(有人已經發布了一個鏈接,線程安全單例在評論中)。

+0

這不是他的容器,所以他不能將實現更改爲用戶併發容器。同步就是答案。 – MeBigFatGuy 2011-04-26 04:31:45

+0

@MeBigFatGUy如果查找功能過於複雜,那麼你可能是對的......但是如果這個功能是在一個散列表中進行簡單的查找,那麼更改爲併發或無鎖容器的工作就會比同步單例實例。 – Kiril 2011-04-26 12:21:54

2

爲您的聽寫實例編寫一個包裝。在這個包裝中同步訪問以確保一次只有一個線程可以訪問lookupAllIndexWords()。

public class DictionaryIndexer { 
    public static IndexWordSet lookupAllIndexWords(newWord) { 
     final Dictionary instance = Dictionary.getInstance(); 
     synchronized (instance) { 
      return instance.lookupAllIndexWords(newWord); 
     } 
    } 
} 

如果封裝了所有使用相同的鎖用於同步的包裝來電來解釋你migth能夠有一個線程安全的解決方案。

+1

小心在簽名中同步而不是在方法中的塊中。其他代碼可以在班級的監視器上同步並鎖定你。請注意,有時這是需要的,但通常不是。 – corsiKa 2011-04-26 04:28:49

+0

@glowcoder你會建議同步Dictionary.getInstance()而不是? – Lynch 2011-04-26 04:31:09

+0

是的,同意glowcoder。如果可能的話,使用專用字段進行同步總是比較安全的,因爲您知道該類擁有鎖定對象,而其他一些類不可能干擾您的同步。 – MeBigFatGuy 2011-04-26 04:45:52

1

從來源:

你有迭代器和狀態都在這個庫:

/** 
* Main word lookup procedure. First try a normal lookup. If that doesn't work, 
* try looking up the stemmed form of the lemma. 
* @param pos the part-of-speech of the word to look up 
* @param lemma the lemma to look up 
* @return IndexWord the IndexWord found by the lookup procedure, or null 
*    if an IndexWord is not found 
*/ 
public IndexWord lookupIndexWord(POS pos, String lemma) throws JWNLException { 
    lemma = prepareQueryString(lemma); 
    IndexWord word = getIndexWord(pos, lemma); 
    if (word == null && getMorphologicalProcessor() != null) { 
     word = getMorphologicalProcessor().lookupBaseForm(pos, lemma); 
    } 
    return word; 
} 



/** 
* Return a set of <code>IndexWord</code>s, with each element in the set 
* corresponding to a part-of-speech of <var>word</var>. 
* @param lemma the word for which to lookup senses 
* @return An array of IndexWords, each of which is a sense of <var>word</var> 
*/ 
public IndexWordSet lookupAllIndexWords(String lemma) throws JWNLException { 
    lemma = prepareQueryString(lemma); 
    IndexWordSet set = new IndexWordSet(lemma); 
    for (Iterator itr = POS.getAllPOS().iterator(); itr.hasNext();) { 
     IndexWord current = lookupIndexWord((POS)itr.next(), lemma); 
     if (current != null) set.add(current); 
    } 
    return set; 
} 

和POS我們發現

private static final List ALL_POS = 
    Collections.unmodifiableList( /* alphazero: this is good news .. */ 
      Arrays.asList(new POS[] {NOUN, VERB, ADJECTIVE, ADVERB})); 

public static List getAllPOS() { 
    return ALL_POS; 
} 

嘗試林奇的回答。它應該工作。