まず、循環ループはありません。
循環ループは、それ自体を指すリンク リストがある場合です。ステップスルーすると、別のスレッドが繰り返し要素をキューの最後に追加する可能性のあるキューがあるだけです。
循環ループを検出する方法は、接続が接続に既に存在するかどうかを確認するhashtable
前にを使用するPing()
ことです。存在する場合は次の要素に移動し、存在しない場合はそれを次に、操作をサーバーにhashtable
呼び出します。Ping
または、最初のping
操作でその正確な時刻にキューのスナップショットを作成し、それをステップオーバーしないようにすることもできます。
A
そうは言っても、2 人の異なる呼び出し元がキューから同じ結果を取得できる場合、キューに何か問題があります。
このコードを実行する正しい方法は、2 つの別個のリストを用意することです。1 つは などのリクエストの接続のキューで、もう 1 つは の接続externalClass.getConnection()
のリストですPing
。あなたのPing
操作が何をしていても、外部クラスがその接続で行っていることに実際には影響を与えるべきではありませconnection
ん.sql connection
Ping
SELECT TOP 1 1
そして、それはあなたの接続が生きていることを意味します. 接続があまりにも長くアイドル状態であり、それ自体を閉じているため、これを実装している可能性が高いため..その場合、SQL dbmsのほとんどすべてのフレーバーが、まさにあなたがしようとしていることを行う接続プーリングをサポートしているため、実際にはすべきではありません。他の実行を待機させることにより、一度に Queue.Count を超える同時接続を防止したい場合を除きます (単純な などのオープン接続のプールを維持するよりもはるかに優れた方法で実行できますint counter
) 。
異なるサーバーへの接続を維持し、複数のサーバー間でリクエストをローテーションしてアドホックな負荷分散を試みない限り、すべての接続のリストと利用可能な接続のキューで上記のソリューションを使用してください。このソリューションの主な利点は、アプリケーションが現在要求を処理している場合でも、アプリケーションを閉じるときにすべての接続を終了できることです。
しかし、あなたの質問に完全に答えるために:
循環ループがあった場合はA -> B -> C -> A
、次のようになります。各要素は、単に a の要素ではなく、リスト内の次の要素を指しqueue
ます。良い例は、サーバーA
をpingし、サーバーB
をpingし、サーバーをpingC
しA
、次のように検出することです。
循環ループを検出する簡単な方法は、一度に 2 つ (または複数) の反復を実行することです。それらを X および Y と呼びます。
X を(またはコンテキスト内で) 2 回踏むたび.Ping()
に、Y を 1 回踏むことになります。ping がループ内で何度も呼び出されないように、Visit
your を呼び出すのではなく、などの新しいメソッドを作成することをお勧めします。Ping
キューが次のように見えると仮定しますA, B, C, A, B...
いくつかの手順の後、X は次のようになります。A, B, C, A
一方、Y は のようになりますA, B
。履歴全体を保存するのではなく、現在の値のみを確認するため、X にステップインすると、新しい値が Y の現在の値と一致するかどうかを確認するため、最終的には常に衝突が発生します。
これは循環ループを検出するための最速または最も効率的な方法ではありませんが、最も単純であり、ループが一般的に小さい場合は、過去のルートの履歴リストを保存するよりも簡単です (場合によっては、コードに大幅な変更が必要になります)。 )。ループが 20 ステップを超える場合に使用できる、はるかに効率的なアルゴリズムがあります (複雑な分岐ツリーなどを処理するように設計されています)。この実装の最悪のケースは、素数のループ要素になることを認識することが重要です。
しかし、これをさらに拡張して 3ステップZ
ごとに 1 回ステップするイテレーターを持つことで、平均してパフォーマンスを向上させることができます。新しい各イテレータの作成による素数)。X
X