我有两个独立的 ChronicleQueues,它们是由独立线程创建的,它们监视 Java 应用程序中的 Web 套接字流。当我在单独的单线程程序中独立读取每个队列时,我可以按预期遍历每个整个队列 - 使用以下最少的代码:
final ExcerptTailer queue1Tailer = queue1.createTailer();
final ExcerptTailer queue2Tailer = queue2.createTailer();
while (true)
{
try( final DocumentContext context = queue1Tailer.readingDocument() )
{
if ( isNull(context.wire()) )
break;
counter1++;
queue1Data = context.wire()
.bytes()
.readObject(Queue1Data.class);
queue1Writer.write(String.format("%d\t%d\t%d%n", counter1, queue1Data.getEventTime(), queue1Data.getEventContent()));
}
}
while (true)
{
try( final DocumentContext context = queue2Tailer.readingDocument() )
{
if ( isNull(context.wire()) )
break;
counter2++;
queue2Data = context.wire()
.bytes()
.readObject(Queue2Data.class);
queue2Writer.write(String.format("%d\t%d\t%d%n", counter2, queue2Data.getEventTime(), queue2Data.getEventContent()));
}
}
在上面,我能够读取所有 Queue1Data 对象,然后是所有 Queue2Data 对象并按预期访问值。但是,当我尝试交错读取队列时(根据 Queue1Data 对象的属性(时间戳)从一个队列中读取对象,读取 Queue2Data 对象,直到时间戳之后的第一个对象(下面的限制变量) ,找到活动的 Queue1Data 对象 - 然后对其进行处理)仅读取 queue2Tailer 中的一个对象后,抛出异常.DecoratedBufferUnderflowException: readCheckOffset0 failed
。失败的简化代码如下(我尝试将外while(true)
循环放在queue2Tailer try
块的内部和外部):
final ExcerptTailer queue1Tailer = queue1Queue.createTailer("label1");
try( final DocumentContext queue1Context = queue1Tailer.readingDocument() )
{
final ExcerptTailer queue2Tailer = queue2Queue.createTailer("label2");
while (true)
{
try( final DocumentContext queue2Context = queue2Tailer.readingDocument() )
{
if ( isNull(queue2Context.wire()) )
{
terminate = true;
break;
}
queue2Data = queue2Context.wire()
.bytes()
.readObject(Queue2Data.class);
while(true)
{
queue1Data = queue1Context.wire()
.bytes()
.readObject(Queue1Data.class); // first read succeeds
if (queue1Data.getFieldValue() > limit) // if this fails the inner loop continues
{ // but the second read fails
// cache a value
break;
}
}
// continue working with queu2Data object and cached values
} // end try block for queue2 tailer
} // end outer while loop
} // end outer try block for queue1 tailer
我已经按照上面的方法进行了尝试,并且在执行处理的函数的开头创建了两个 Tailers(在相对简单的 Java 应用程序中单击按钮时执行的私有函数)。基本上我采用了独立工作的循环,并将其放在函数的另一个循环中,预计不会出现问题。我想我在如何定位和用于读取对象方面遗漏了一些至关重要的东西,但我无法弄清楚它是什么 - 因为相同的基本代码在独立读取队列时起作用。使用isNull(context.wire())
来确定队列中何时不再有对象我从其中一个示例中获得,但我不确定这是在顺序处理队列时确定队列中何时不再有对象的正确方法。
任何建议,将不胜感激。