Java 从ActiveMQ DestinationSource.getQueues响应正确迭代队列
由于以下代码中的某些原因,destinationSource.getQueues返回的是CopyOnWriteArraySet,而不是简单的集合。这是一个问题,因为for循环在集合已满之前开始处理,并且由于CopyOnWriteArraySet的性质,它将只处理循环之前集合中的项。我知道我可以抛出一个线程。在那里睡觉,但这并不能解决根本的问题。是否有任何理由将其作为CopyOnWriteArraySet而不是集合返回?还有什么方法可以迭代CopyOnWriteArraySet以确保覆盖所有项目,即使是在迭代过程中添加的项目Java 从ActiveMQ DestinationSource.getQueues响应正确迭代队列,java,concurrency,set,activemq,copyonwritearraylist,Java,Concurrency,Set,Activemq,Copyonwritearraylist,由于以下代码中的某些原因,destinationSource.getQueues返回的是CopyOnWriteArraySet,而不是简单的集合。这是一个问题,因为for循环在集合已满之前开始处理,并且由于CopyOnWriteArraySet的性质,它将只处理循环之前集合中的项。我知道我可以抛出一个线程。在那里睡觉,但这并不能解决根本的问题。是否有任何理由将其作为CopyOnWriteArraySet而不是集合返回?还有什么方法可以迭代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();
正如你所说,这种行为是我们的天性。队列列表可以与线程同时更改。通过返回CopyOnWriteArraySet ActiveMQ,您可以安全地在线程中使用数据结构,而不会更改ConcurrentModificationException,并且该数据结构将保持最新 由于可以随时添加新队列,因此无法等待它们全部完成
如果您想知道何时添加新队列,然后做一些响应,最好的方法是侦听适当的ActiveMQ。此功能将允许您响应消息队列的添加、使用者和生产者的添加以及相同的删除。Think link有一个代码示例。我在从连接获取所有队列时遇到了相同的问题。 每当我从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) {...}
从现在起,我总是能得到正确数量的队列,并能遍历整个集合
尽管如此,我真的不知道为什么 您的问题是什么?更新的问题,对不起,应该更具体谢谢,解决方案成功了!那么Thread.sleep真的是解决方案吗?因为如果不这样做,它会处理集合中的3个队列,而不是现有的~500个队列。我已经更新了答案。请接受,如果它是你正在寻找的。