2012-04-24 44 views
0

我有一個併發的連接隊列。有一個ping任務定期檢查隊列中的所有可用連接以執行ping操作,同時應用程序可以請求隊列中的連接以供其使用。檢測併發隊列中的循環循環

什麼是檢測循環循環的好方法,以便ping任務可以完成其當前執行?

編輯:

示例:假設併發隊列具有連接A,B和C.

有一個平的任務,遍歷該隊列。所以在這個例子中,它會做A.ping(),B.ping()C.ping()。現在有一個外部類也要求隊列中的連接,而ping任務也在隊列中迭代。所以假設A.ping()已經完成並且externalClass.getConnection()將返回A。在ping任務完成C.ping()時,發生externalClass.releaseConnection(A)。現在隊列的順序是B,C and A。因此,在完成C.ping()之後,ping任務將再次找到A,此時任務必須決定A已經被ping並且應該結束當前執行。

+0

請舉例說明發生循環循環的示例情況 – HelloWorld 2012-04-25 03:24:36

+0

使用示例編輯 – Prasanna 2012-04-25 04:37:15

回答

0

貴平只能ping通的機器呢,還是ping通一體機,其中執行ping了下,這會ping下,再等等?

解決此問題的一種方法是讓每臺機器都跟蹤它是否已被ping通。如果它已經,並且它收到一個新的ping,它不會再次發送ping。

另一種方式來解決,這將是通過什麼機器給定的ping包已經與它一起看到的信息,並在一個ping數據包到達已經看到一臺機器,它會終止。

+0

連接池具有到同一臺計算機的所有連接,這意味着所有連接都會ping同一臺計算機。 – Prasanna 2012-04-24 22:35:24

+0

那麼問題是什麼呢?當您ping通它時,機器是否可以ping通?或者是什麼?你是什​​麼意思的一個循環? – moowiz2020 2012-04-24 23:05:33

1

對於初學者,您沒有循環循環。

當您有一個鏈接列表指向自己時,循環就是循環。你只需要一個隊列,當你逐步完成時,可能會有另一個線程將重複的元素添加到隊列的末尾。

檢測圓形環路的方法是使用一個hashtable,每個Ping()之前檢查連接的連接已經存在,如果這樣做,那麼你只是繼續前進到下一個元素,如果它不存在然後將其添加到hashtable,然後將您的Ping操作調用到服務器。

或者你可以有你的初始ping操作使隊列的快照,準確的時間,在它不是一步。

隨着中說,東西是非常錯誤的與您的隊列中,如果你可以有兩種不同的來電者得到相同的結果A從隊列中。

執行此代碼的正確方法是有兩個單獨的列表,一個是請求的連接隊列,如externalClass.getConnection(),另一個是Ping的連接列表。無論您Ping操作真正做起來應該不會影響任何東西,任何外部類是用它做的連接,例如假設connectionsql connection然後Ping應該執行這樣的事情:

SELECT TOP 1 1 

僅此而已,那這意味着你的連接仍然存在。因爲你可能正在實現這一點,因爲連接閒置時間太長,並且自己關閉......在這種情況下,你真的不應該這麼做,因爲幾乎所有的sql dbms都支持連接池,而這正是你想要做的。除非您希望通過讓其他執行等待來同時阻止多個Queue.Count併發連接(這本身可以通過更好的方式保持一個開放連接池,例如簡單的int counter

除非您保持與不同服務器的連接,並嘗試通過在多個服務器之間輪轉請求來實現臨時負載均衡,然後使用我的上述解決方案以及所有連接和可用連接隊列的列表。該解決方案的主要優點是,即使應用程序當前正在處理請求,您也可以終止應用程序關閉時的所有連接。

但是,在回答你的問題完整性:

如果沒有有一個圓形的環,將是這樣的:A -> B -> C -> A其中每個元素將指向列表中的下一個,而不是僅僅是元素在queue。一個很好的例子就是你Ping服務器A其中坪的服務器B其中坪的服務器C然後坪A,你可以按如下方式檢測出來:

簡單的方法來檢測的圓環是通過它來運行兩個(或多個)迭代同時,我們會打電話給他們X和Y

對於你一步(或.Ping()在context)X每一秒時間,你一步ÿ一次。你可能想使一個新的方法,如Visit,而不是在循環中調用你Ping,使平不叫了很多次。

假設隊列看起來像A, B, C, A, B...

走了幾步X的樣子:A, B, C, A而在Y的樣子A, B。你要做的就是商店的整個歷史,你只能看電流值,所以當你在X步你檢查新的值Y的當前值相匹配,因此,我們將最終總能得到一個碰撞。

這不是檢測循環循環的最快或者最有效的方法,但它是最簡單的,如果你的循環一般比較小,比存儲歷史路由的歷史列表更容易(在某些情況下需要代碼的重大變化)。當你的循環超過20步時(它們被設計用於處理複雜的分支樹等等)時,可以使用更高效的算法。重要的是要認識到,這種實現的最壞情況將是循環元素的主要數量。

但你可以通過只擴展這方面進一步有Z迭代這對於每三個X步驟步驟一次,在這一點上它不是一個真正值得添加額外的一個步驟,每5個X步驟或7,並提高平均性能等等(通過創建每個新的迭代器訪問下一個增量素數)。

+0

連接不是JDBC連接,而是節點連接,ping()是節約服務的方法。是的,現在我正在使用類似於你所建議的解決方案,使用HashSet而不是HashTable。但是我發現很難理解你使用2個列表的解釋。我希望打開的連接保持活動狀態,以便externalClass可以使用它。 – Prasanna 2012-04-25 06:13:20

0

也許我不明白你在那裏做什麼,但對我來說,看起來問題是因爲Ping任務不像外部任務那樣遵循入隊/出隊規則。那麼如何讓Ping任務首先將連接出列,刷新其「ping值」並將其排入隊列呢?

如果您的目標是保證外部任務總是以最小的ping值獲得連接,那麼您可能需要使用堆而不是隊列。