【问题标题】:A multi-agent system that uses Producer-Consumer pattern?使用生产者-消费者模式的多代理系统?
【发布时间】:2018-06-23 15:42:28
【问题描述】:

我正在尝试实现一个Producer-Consumer 模式,它使用多代理而不是多线程作为工作人员。

据我了解,典型的多线程实现使用BlockingQueue,其中一个Producer 线程将信息放在队列中,并有多个Consumer 线程提取数据并执行一些处理功能。

所以按照相同的逻辑,我的设计将使用一个Producer 代理来生成数据并将其发送到多个Consumer 代理。起初猜测,我认为我应该在Consumer 代理之间使用共享 BlockingQueue 并让代理访问队列并检索数据。但我不知道这样做是否容易,因为我认为代理没有任何共享内存,直接将信息作为 ACL 消息发送到Consumer 代理要简单得多.

考虑到这一点很重要,因为我的多智能体设计将处理大量数据。所以我的问题是,在 Jade 中,如果我向单个代理发送多个 ACL 消息会发生什么?代理会忽略其他消息吗?

这个post 有一个答案建议 "..在 JADE 框架内,代理为 ACLMessages 提供了一个“收件箱”,基本上是一个 BlockingQueue 对象,其中包含收到的消息列表。代理能够观察它自己的列表并将它们视为其生命周期的进行。容器不具有此功能..."。这种说法正确吗?如果这是真的,那么其他消息只是在队列中等待,我的设计将信息直接发送到Consumer 代理将是理想的,但我在 ACLMessage 类上没有看到任何BlockingQueues。

【问题讨论】:

  • 查看jade.core.Agent#receive()。您将看到阻塞队列的 MessageQueue 和同步。如果您的消息数量超过队列的最大大小(MessageQueue.getMaxSize),您应该不明白,您的第一条消息将被删除(InternalMessageQueue.addLast)
  • 我了解,我已尝试实施该设计,但我注意到代理变得越来越慢,因为队列中充满了其他 ACL 消息。我猜这与消息队列的大小或长度有关。我怎么解决这个问题 ?消费者代理很慢,因为它们在接收其他 ACL 消息时处理它们。
  • 消费者代理是否一次只处理一条消息?我的意思是循环行为的一次迭代......也许你应该创建更多的消费者代理?
  • 感谢您的回答。 producer 代理从文件中读取数据并向每个代理发送一行(第一行到第一个代理,第二行到第二...等等)。每个consumer 代理在收到消息后立即对其进行处理。我相信consumer 代理滞后,因为他们无法处理producer 代理填充的消息队列。够清楚吗?所以我的代码的问题是它向多个代理发送了很多消息,我不知道如何解决/优化这个。
  • 您是否尝试过在消费者代理中一次处理多条消息?像这样: int size = myAgent.getCurQueueSize();如果(大小 == 0){ 块();返回; } for(int i = 0; i

标签: java multithreading producer-consumer agents-jade multi-agent


【解决方案1】:

是的,消息将在队列中,代理不会忽略它们。

ACLMessage 只是一个消息对象,在代理之间发送。每个代理都有自己的消息队列 (jade.core.MessageQueue) 和几种处理通信的方法。

如果你查看Agent 类文档,你可以找到类似的方法

  • receive() - 非阻塞接收,返回队列中的第一条消息,如果队列为空,则返回 null
  • receive(MessageTemplate pattern) - 行为与前一个类似,但您也可以指定消息的模式,例如特定的发件人 AID、对话 ID 以及组合。
  • blockingReceive() - 阻止接收,阻止代理,直到消息出现在队列中
  • blockingReceive(MessageTemplate pattern) - 阻塞接收,有模式

还有一些阻塞接收的方法,你可以设置超时时间。

另外值得一提的是,如果您在 Behaviour 类中定义代理逻辑,您也可以只阻止行为,而不是阻止整个代理。

ACLMessage msg = agent.receive();    
if (msg != null) {
    // your logic
} else {
    block();            
}

不同之处在于,行为内部的block() 方法只是将您的行为标记为被阻止并将其从代理的活动行为池中删除(当接收到消息或通过restart() 方法重新启动行为时,它会添加回活动池)允许执行其他代理的行为,blockingReceive() 完全阻止您的代理及其所有行为,直到他收到消息。

【讨论】:

  • 感谢您的回答。我正在使用 CyclicBehaviour 类来处理收到的 ACL 消息,因为它是推荐的。确实,ACL 消息在队列中被阻塞并且不会被忽略,但是随着队列被其他 ACL 消息填满,代理会逐渐变慢。我猜这与消息队列的大小或长度有关。我怎么解决这个问题 ? Consumer 代理很慢,因为它们在接收其他 ACL 消息时处理它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 2021-04-30
相关资源
最近更新 更多