2

何らかの理由で、次のコードでは単純な ではなくdestinationSource.getQueues()が返されます。for ループはがいっぱいになる前に処理を開始し、その性質上ループ前の項目のみを処理するため、これは問題です。そこに を投入できることはわかっていますが、根本的な問題は解決しません。ではなくとして返される理由はありますか? また、反復中に追加されたものであっても、すべてのアイテムが確実にカバーされるようにする方法はありますか?CopyOnWriteArraySetSetSetCopyOnWriteArraySetSetThread.sleep()CopyOnWriteArraySetSetCopyOnWriteArraySet

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();
4

2 に答える 2

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) {...}

これからは、常に適切な数のキューを取得し、完全なセットを反復処理できます。

ただし、理由はよくわかりません;)

于 2016-06-02T12:32:11.180 に答える
1

おっしゃる通り、このように振る舞うのがCopyOnWriteArraySetの性質です。キューのリストは、スレッドと同時に変更できます。CopyOnWriteArraySetActiveMQ を返すことで、スレッドで安全に使用でき (変更なしConcurrentModificationException)、最新の状態を保つデータ構造が提供されます。

新しいキューはいつでも追加できるため、すべてが完了するまで「待機」する方法はありません。

新しいキューがいつ追加されたかを知りたい場合、それに応じて何かを行うには、適切な ActiveMQアドバイザリ メッセージをリッスンするのが最善の方法です。この機能により、メッセージ キューの追加、コンシューマーとプロデューサーの追加、およびそれらの削除に対応できます。リンクにコード例があると思います。

于 2015-07-08T18:56:09.823 に答える