Java 从ActiveMQ DestinationSource.getQueues响应正确迭代队列

Java 从ActiveMQ DestinationSource.getQueues响应正确迭代队列,java,concurrency,set,activemq,copyonwritearraylist,Java,Concurrency,Set,Activemq,Copyonwritearraylist,由于以下代码中的某些原因,destinationSource.getQueues返回的是CopyOnWriteArraySet,而不是简单的集合。这是一个问题,因为for循环在集合已满之前开始处理,并且由于CopyOnWriteArraySet的性质,它将只处理循环之前集合中的项。我知道我可以抛出一个线程。在那里睡觉,但这并不能解决根本的问题。是否有任何理由将其作为CopyOnWriteArraySet而不是集合返回?还有什么方法可以迭代CopyOnWriteArraySet以确保覆盖所有项目,

由于以下代码中的某些原因,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个队列。我已经更新了答案。请接受,如果它是你正在寻找的。