我有一个优先级队列类,我在Java中实现,因为它是一个队列数组。我需要一种好的方法(不使用序列化)在每个“事务”之后记录和存储优先级队列的内容,或者从优先级队列中排队对象()/ dequeue()。如果需要由文本文件中的程序重建优先级队列,它应该作为备份。
我有一些想法和每个问题:
在每个“事务”之后,循环遍历队列,并使用对象之间的分隔符将每个队列写入文件中的一行。 - 我的问题是它需要将所有对象出列并重新入队,这看起来非常低效。
每次入队或出列后,只需编写该对象或从文件中删除该对象即可。 - 我的问题是:如果这是我应该采取的方法,我很难想出一种在出列后轻松找到并删除对象的方法。
任何提示/提示/建议都将不胜感激!
答案 0 :(得分:1)
要遍历队列,您可以迭代它。这是非破坏性的(但只是松散的线程安全)
每次将队列内容写入磁盘可能会非常慢。对于典型的硬盘驱动器,一个小队列将需要大约20 ms来写入。即最多每秒50次。如果您使用SSD,对于小型队列来说这会快得多,但即使您不使用序列化,您仍然需要编组数据。
另一种方法是使用旨在支持事务,队列和持久性的JMS服务器。典型的JMS服务器每秒可处理大约10,000条消息。有许多好的免费服务器可用。
答案 1 :(得分:1)
我会将您的要求作为日志模式实现。在文件的末尾,追加每个队列及其优先级,追加每个队列。如果您的消息收发服务器崩溃,您可以重播日志文件,并最终得到适当的状态。
显然,您的日志文件会随着时间的推移而变大。要解决这个问题,您需要经常轮换日志文件。为此,请在某个时间点序列化队列,然后开始登录新文件。您甚至可以通过在将数据结构的快照写入磁盘的同时将事务记录到旧日志和新日志来锁定状态(冻结队列请求)来实现此目的。快照完成后,写一个指示到磁盘的指针,您可以删除旧日志。
写入时间和空间为n,重放应该很少并且相对较快。
答案 2 :(得分:0)
在第二种方法中轻松找到对象......我有几个建议::
答案 3 :(得分:0)
还有一个建议:(考虑是否一定要使用一个文件):
如果您的对象编号不是很大,请将每个对象存储到单独的文件中。当然,您需要为每个对象创建一个唯一的标识符,您也可以使用此标识符作为文件名。这样,您始终可以根据存储在对象中的标识符添加或删除单个文件。如果对象具有无法修改的各种类,则只需存储将标识符映射到对象的哈希映射。因此,在将对象添加到队列之前,您需要创建一个标识符,然后将该对象和标识符作为一对添加到映射中,并将新文件名写为标识符并包含该对象。我将在删除和重新加载方面做些什么,因为它只不过是练习。
个人而言,我赞成罗伯特哈维在对这个问题的评论中提出的建议。考虑使用数据库,特别是如果你的项目已经有了。这样可以比在文件中定位位置更容易,更快速地存储对象和删除对象。因为即使您在文件中找到对象的位置,很可能您需要再次编写整个文件(仅在没有该对象的情况下)。这与循环没有什么不同。使用数据库,可以避免所有这些麻烦。