Multithreading 当8-10个参与者同时运行时,一些Scala参与者进入等待状态

Multithreading 当8-10个参与者同时运行时,一些Scala参与者进入等待状态,multithreading,scala,rabbitmq,Multithreading,Scala,Rabbitmq,在我的模型中,大约有8-9个Scala演员。 每个参与者在RabbitMQ服务器上都有自己的队列 在每个参与者的act方法中。它不断地列在队列中 像 我使用rabbitMq QManager getMessage方法 def getMessage: MyObject = { getConnection val durable = true channel.exchangeDeclare(EXCHANGE, "direct", durable) channel.qu

在我的模型中,大约有8-9个Scala演员。 每个参与者在RabbitMQ服务器上都有自己的队列

在每个参与者的act方法中。它不断地列在队列中 像

我使用rabbitMq QManager getMessage方法

def getMessage: MyObject = {
    getConnection
    val durable = true
    channel.exchangeDeclare(EXCHANGE, "direct", durable)
    channel.queueDeclare(QUEUE, durable, false, false, null)
    channel queueBind (QUEUE, EXCHANGE, _ROUTING_KEY)
    consumer = new QueueingConsumer(channel)
    channel basicConsume (QUEUE, false, consumer)

    var obj = new MyObject
    try {
      val delivery = consumer.nextDelivery
      val msg = new java.io.ObjectInputStream(
        new java.io.ByteArrayInputStream(delivery.getBody)).readObject()
      obj = msg.asInstanceOf[MyObject]
      channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false)
    } catch {
      case e: Exception =>logger.error("error in Get Message", e);endConnection
    }
    endConnection
    obj
  }
所有9个参与者都有自己的对象类型和QManager

在GetMessage中,我使用Rabbitmq QueueConsumer

 val delivery = consumer.nextDelivery
nextDelivery方法在队列中找到对象时返回一个对象 此方法将参与者置于等待状态

当我开始所有8名演员时,他们中只有4人表现良好,其他人则没有说明。 我已经测试了每一个演员,他们独立运行时效果良好

当我启动4个以上的演员时,问题就出现了


scala参与者的线程是否存在任何问题

你所有的演员都在奔跑;他们从不休息。由于演员在一个公共线程池中共享,这意味着幸运的赢家演员一直在运行,而不幸的输家根本没有时间。如果您希望有一个始终为自己占用整个线程的实体,通常最好使用java
线程
,或者至少使用
接收
,而不是
反应
。您还可以增加演员池的大小以匹配演员的数量,但通常情况下,如果您有大量演员,并且所有演员都在运行,您应该更仔细地考虑如何构建您的程序。

免责声明:我是Akka的PO

正如Rex所说,您正忙于等待、占用共享线程池中的线程

我不知道您是否可以选择测试Akka,但我们支持AMQP消费者(和制片人)作为参与者:

生成AMQP消息:

    val exchangeParameters = ExchangeParameters("my_topic_exchange", Topic)
    val producer = AMQP.newProducer(connection, ProducerParameters(Some(exchangeParameters), producerId = Some("my_producer"))
producer ! Message("Some simple sting data".getBytes, "some.routing.key")
val exchangeParameters = ExchangeParameters("my_topic_exchange", Topic)
val myConsumer = AMQP.newConsumer(connection, ConsumerParameters("some.routing.key", actorOf(new Actor { def receive = {
  case Delivery(payload, _, _, _, _, _) => log.info("Received delivery: %s", new String(payload))
}}), None, Some(exchangeParameters)))
使用AMQP消息:

    val exchangeParameters = ExchangeParameters("my_topic_exchange", Topic)
    val producer = AMQP.newProducer(connection, ProducerParameters(Some(exchangeParameters), producerId = Some("my_producer"))
producer ! Message("Some simple sting data".getBytes, "some.routing.key")
val exchangeParameters = ExchangeParameters("my_topic_exchange", Topic)
val myConsumer = AMQP.newConsumer(connection, ConsumerParameters("some.routing.key", actorOf(new Actor { def receive = {
  case Delivery(payload, _, _, _, _, _) => log.info("Received delivery: %s", new String(payload))
}}), None, Some(exchangeParameters)))

另一个选项是使用参与者消费和生成AMQP消息

我可以知道如何增加参与者池的大小吗