出于某些原因,在以下代码中,destinationSource.getQueues()
返回的是CopyOnWriteArraySet
,而不是简单的Set
。这是一个问题,因为for循环在Set
已满之前开始处理,由于CopyOnWriteArraySet
的性质,它只会在循环之前处理Set
中的项目。我知道我可以在那里抛出Thread.sleep()
,但这并不能解决潜在的问题。是否有任何理由将其作为CopyOnWriteArraySet
而不是Set
返回?还有什么方法可以迭代CopyOnWriteArraySet
以确保所有项目都被覆盖,甚至是在迭代期间添加的项目?
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
ActiveMQConnection activeMQConnection = (ActiveMQConnection) connectionFactory.createConnection();
activeMQConnection.start();
DestinationSource destinationSource = activeMQConnection.getDestinationSource();
Set<ActiveMQQueue> queues = destinationSource.getQueues();
for(ActiveMQQueue queue : queues) {
queueNames.add(queue.getPhysicalName());
}
activeMQConnection.close()
编辑:这是我提出的解决方案,虽然它并不完美,但它确保您可以获得所有队列,直到添加队列之间的时间超过1秒。
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
ActiveMQConnection activeMQConnection = (ActiveMQConnection) connectionFactory.createConnection();
activeMQConnection.start();
DestinationSource destinationSource = activeMQConnection.getDestinationSource();
Set<ActiveMQQueue> queues = destinationSource.getQueues();
do {
for(ActiveMQQueue queue : queues) {
String physcialName = queue.getPhysicalName();
if(!queueNames.contains(physcialName)) {
queueNames.add(physcialName);
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
log(e.toString());
}
}while(queueNames.size() < queues.size());
activeMQConnection.close();
答案 0 :(得分:3)
从连接中获取所有队列时遇到了同样的问题。 每当我从DestinationSource获得队列,然后在此集合之后迭代(foreach), 我得到了不同数量的队列(在迭代循环中,我总是得到比初始队列更多的队列)。
DestinationSource ds = connection.getDestinationSource();
Set<ActiveMQQueue> queues = ds.getQueues();
log.debug("Found '" + queues.size() + "' queues");
for (ActiveMQQueue queue : queues) {...}
然后,我像这样添加了一个目标源的监听器
DestinationSource ds = connection.getDestinationSource();
Set<ActiveMQQueue> queues = ds.getQueues();
// Add listener:
ds.setDestinationListener(event -> event.hashCode());
log.debug("Found '" + queues.size() + "' queues");
for (ActiveMQQueue queue : queues) {...}
从现在开始,我总能获得正确数量的队列,并且可以遍历整个队列。
尽管如此,我真的不知道为什么;)
答案 1 :(得分:1)
正如你所说,CopyOnWriteArraySet以这种方式行事的本质。队列列表可以与您的线程同时更改。通过返回CopyOnWriteArraySet
ActiveMQ,您将获得一个可在您的线程中安全使用的数据结构(不会更改ConcurrentModificationException
),并且会保持最新状态。
由于可以随时添加新队列,因此在完成所有队列之前无法“等待”。
如果您想知道何时添加新队列然后做出响应,最好的方法是听取相应的ActiveMQ advisory message。此工具将允许您响应消息队列添加,消费者和生产者添加,以及删除它们。 Think link有一个代码示例。