对于初学者,您没有循环。
循环循环是指您有一个指向自身的链表。您只有一个队列,当您逐步完成它时,可能会有另一个线程将重复的元素添加到队列的末尾。
检测循环循环的方法是使用hashtable
, 在每次Ping()
检查连接中是否已经存在连接之前,如果存在,则继续移动到下一个元素,如果不存在,则将其添加到hashtable
然后你调用你的Ping
操作到服务器。
或者你可以让你的初始ping
操作在那个确切的时间制作队列的快照,而不是越过它。
话虽如此,如果您可以让两个不同的呼叫者从队列中获得相同的A
结果,那么您的队列就会出现问题。
执行此代码的正确方法是有两个单独的列表,一个是请求的连接队列,例如,externalClass.getConnection()
另一个是连接的列表Ping
。无论您的Ping
操作在做什么,它都不应该影响任何外部类对其连接所做的任何事情,例如假设connection
是 a sql connection
thenPing
应该执行如下操作:
SELECT TOP 1 1
仅此而已,这将意味着您的连接仍然存在。因为您可能会实施此操作,因为连接空闲时间过长并且会自行关闭。在这种情况下,您真的不应该这样做,因为几乎任何类型的 sql dbms 都支持连接池,这正是您想要做的。除非您想通过让其他执行等待来阻止超过 Queue.Count 的并发连接(这本身可以通过更好的方式来保持打开的连接池,例如简单的int counter
)
除非您保持与不同服务器的连接并尝试通过在多个服务器之间轮换请求来进行一些临时负载平衡,否则请使用我上面的解决方案以及所有连接列表和可用连接队列。此解决方案的主要好处是您可以在应用程序关闭时终止所有连接,即使它们当前正在处理请求。
但是,为了完整地回答您的问题:
如果你确实有一个循环,它看起来像这样:A -> B -> C -> A
每个元素都指向列表中的下一个元素,而不仅仅是 a 中的元素queue
。一个很好的例子是你 Ping 服务器A
,它 ping 服务器B
,它 ping 服务器C
,然后 ping 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
步骤执行一次的迭代器,此时实际上不值得添加一个每 5X
步或 7 步执行一次的额外迭代器,依此类推(访问下一个增量质数与每个新迭代器的创建)。