2011-04-16 48 views
0

我有一些代碼,一個Ruby類的類方法FootballSeries.find(123),執行一個API調用...由於擔心線程安全性,一次只有一個線程可能會輸入此方法。由於最近API的一些變化,我還支持以下... FootballSeries.find('Premiership'),第二個變種(請參閱下面的實現)僅進行臨時調用,以查看是否可以找到ID,然後使用ID遞歸調用自己。遞歸函數可以釋放它自己的互斥量嗎?

class FootballSeries 
    @find_mutes = Mutex.new 
    class << self 
    def find(series_name_or_id) 
     @find_mutex.synchronize do 
     if series_name_or_id.is_a?(String) 
      if doc = search_xml_document(series_name_or_id) 
      if doc.xpath('//SeriesName').try(:first).try(:content) == series_name_or_id 
       @find_mutex.unlock 
       series = find(doc.xpath('//seriesid').first.content.to_i) 
       @find_mutex.lock 
       return series 
      end 
      end 
     elsif series_name_or_id.is_a?(Integer) 
      if doc = xml_document(series_name_or_id) 
      Series.new(doc) 
      end 
     end 
     end 
    end 
    end 
end 

沒有行9和11,有一個recursive mutex lock: deadlock錯誤(這使得足夠的理智......所以我的問題是,我可以釋放並重新鎖定互斥。(我重新鎖定,這樣當synchronize退出,我不會得到一個錯誤解鎖,我沒有自己的互斥......但如果這是需要我沒有測試)

這是一個理智的實現,或者我會得到更好的服務具有find()呼叫的兩個個體方法,每個方法都用自己的互斥鎖保護?(例如find_by_idfind_by_name

我現在的工作(或至少似乎工作)。

最後,獎勵積分 - 我將如何測試這種安全方法?

+0

遞歸調用的要點是什麼?爲什麼不簡單地說,如果給出了一個字符串,找到合適的id,並繼續方法,就好像給了id一樣? – 2011-04-16 18:32:21

+0

'xml_document'和'search_xml_document'是不同的,搜索XML只返回一個'id'和'name'。 此處的實現細節並不重要,這可能很容易成爲探索使用互斥鎖的一個人爲的例子。 – 2011-04-16 18:55:03

回答

0

這對我來說不太合適,因爲@find_mutex.unlock將允許同時輸入其他方法。此外,我不認爲使用遞歸通常是這種方法調度 - 實際上你有兩個方法塞進一個。我一定會分開這兩個,如果你想能夠用不同的參數類型調用一個方法,只需檢查參數的類型並調用其中一個。如果您不需要公開find_by_idfind_by_name,則可以將它們設爲私有,並且僅將mutex.synchronize僅用於find

+0

這就是我認爲的......因爲從本質上來說,至少我讀到的方式是,當互斥鎖被解鎖時,對find()的結果的賦值是非確定性的......返回,在互斥體內返回將返回分配的任何東西。 (雖然我還不確定是否有可能另一個線程在那個時候鎖定,如果我保留它,由於我現有的鎖定) – 2011-04-17 14:29:10

相關問題