Для начала у вас нет круговой петли.
Круговой цикл - это когда у вас есть связанный список, который указывает на себя. У вас просто есть очередь, которая, когда вы проходите через нее, может иметь другой поток, добавляющий повторяющиеся элементы в конец очереди.
Способ обнаружения круговой петли заключается в использовании hashtable
, перед каждым Ping()
вы проверяете, существует ли соединение в соединении, если оно происходит, то вы просто переходите к следующему элементу, если его не существует затем вы добавляете его в hashtable
, а затем вы вызываете свою операцию Ping
на сервер.
Или вы можете просто выполнить начальную операцию ping
, сделать моментальный снимок очереди в это точное время, а не наступать на нее.
С учетом сказанного, что-то очень не так с вашей очередью, если у вас могут быть два разных абонента, получающих одинаковый результат A
в очереди.
Правильный способ выполнения этого кода состоит в том, чтобы иметь два отдельных списка, один из которых представляет собой очередь соединений для запросов, таких как externalClass.getConnection()
, а другой список соединений для Ping
.Независимо от Ping
операции делает это на самом деле ничего такого, что любой внешний класс делает с ним не должно повлиять на это соединение, например предполагающей connection
является sql connection
то Ping
должен выполнить что-то вроде этого:
SELECT TOP 1 1
И больше ничего, что будет означать, что ваше соединение остается в живых. поскольку вы, скорее всего, реализуете это, потому что соединения простаивают слишком долго и закрываются сами .., в этом случае вы действительно не должны, потому что в значительной степени любой вкус sql dbms поддерживает объединение пулов, которое делает именно то, что вы пытаетесь сделать. Если вы не хотите предотвратить одновременное одновременное соединение с Queue.Count одновременно, ожидая других ожиданий (что само по себе может быть сделано гораздо лучше, если поддерживать пул открытых соединений, например простой int counter
)
Если только ваш поддерживая соединения с разными серверами и пытаясь выполнить некоторую балансировку нагрузки adhoc, вращая запросы на нескольких серверах, затем используйте мое вышеописанное решение со списком всех подключений и очередью доступных подключений. Основное преимущество этого решения заключается в том, что вы можете завершить все подключения, когда приложение закрывается, даже если они в настоящее время обрабатывают запросы.
Но для полноты в ответ на ваш вопрос:
Если вы сделал имеют круглую петлю он будет выглядеть следующим образом: A -> B -> C -> A
, где каждый элемент будет указывать на следующий в списке, а не просто элементов в queue
. Хорошим примером может служить вы пинг сервера A
который пингует сервер B
который пингует сервер C
который затем свистит A
и вы бы обнаружить его следующим образом:
Простой способ обнаружения круговых петель является запуск двух (или нескольких) итераций через него мы назовем их X и Y.
Для каждого второго шага (или .Ping()
в вашем контексте) X, вы шаг Y один раз. Возможно, вы захотите сделать новый метод, например Visit
, вместо того, чтобы называть ваш Ping
так, чтобы ping не вызывался много раз в цикле.
Предполагая, что очередь выглядит A, B, C, A, B...
После нескольких шагов X будет выглядеть так: A, B, C, A
в то время как Y будет выглядеть A, B
. Что вы делаете, так это то, что вы не сохраните всю историю, вы только посмотрите на текущие значения, поэтому, когда вы ступите в X, вы проверяете, соответствует ли новое значение текущему значению Y, таким образом, мы, в конечном счете, всегда получим столкновение.
Это не самый быстрый или эффективный способ обнаружения циклических циклов, но он является самым простым и если ваши петли обычно будут небольшими, это проще, чем хранить исторический список прошлых маршрутов (что в некоторых случаях требует значительные изменения в коде). Существуют гораздо более эффективные алгоритмы, которые можно использовать, когда ваши петли занимают более 20 шагов (они предназначены для решения сложных ветвящихся деревьев и т. П.). Важно признать, что наихудший случай для этой реализации будет простым числом элементов цикла.
Но вы можете улучшить производительность в среднем, только расширяя это еще иметь Z
итератор, который ступает один раз на каждые три X
шагов, на данный момент это не на самом деле стоит добавить еще одну программу, которая ступает через каждые 5 X
шагов или 7 и и так далее (посещение следующего инкрементного простого числа с созданием каждого нового итератора).
Просьба привести примерное обстоятельство, когда происходит циклическая петля – HelloWorld
Отредактировано с помощью примера – Prasanna