Multithreading 如何检查akka应用程序中配置了什么调度器

Multithreading 如何检查akka应用程序中配置了什么调度器,multithreading,akka,Multithreading,Akka,我在conf文件中有以下条目。但我不确定是否正在使用此调度程序设置,以及使用的最终并行度值是多少 akka{ actor{ default-dispatcher { type = Dispatcher executor = "fork-join-executor" throughput = 3 fork-join-executor {

我在conf文件中有以下条目。但我不确定是否正在使用此调度程序设置,以及使用的最终并行度值是多少

        akka{
      actor{
        default-dispatcher {
              type = Dispatcher
              executor = "fork-join-executor"
              throughput = 3
              fork-join-executor {
                parallelism-min = 40
                parallelism-factor = 10
                parallelism-max = 100
              }
            }
       }
    }
我有8个核心的机器,所以我希望80个并行线程处于就绪状态 40min<80(8*10因子)<100max。我想看看akka对max parallel thread使用了什么值。
我创建了45个子角色,在我的日志中,我正在打印线程id[application akka.actor.default dispatcher xx],并且我没有看到超过20个线程并行运行。

假设您有一个
ActorSystem
实例,您可以检查其配置中设置的值。这就是如何获得在配置文件中设置的值的方法:

val system=ActorSystem()
val config=system.settings.config.getConfig(“akka.actor.default dispatcher”)
config.getString(“类型”)
config.getString(“执行者”)
config.getString(“吞吐量”)
config.getInt(“fork-join-executor.parallelism-min”)
config.getInt(“fork join executor.parallelism max”)
config.getDouble(“fork-join-executor.parallelism factor”)
我希望这有帮助。有关特定配置设置的更多详细信息,您也可以参阅第页

更新

我在Akka挖掘了更多信息,以了解它在您的设置中的确切用途。正如您可能已经预料到的那样,它使用了
ForkJoinPool
。用于构建它的并行性如下所示:

object ThreadPoolConfig {
  ...
  def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int =
math.min(math.max((Runtime.getRuntime.availableProcessors * multiplier).ceil.toInt, floor), ceiling)
  ...
}

此函数在某些时候用于构建
ForkJoinExecutorServiceFactory

新ForkJoinExecutorServiceFactory(
验证(tf),
ThreadPoolConfig.scaledPoolSize(
config.getInt(“最小并行度”),
config.getDouble(“并行度因子”),
config.getInt(“最大并行度”),
异步模式)
无论如何,这就是将用于创建
ForkJoinPool
的并行性,它实际上是的一个实例。现在我们要问这个池使用了多少线程?简单的回答是,只有在需要时,它才会使用整个容量(在我们的例子中是80个线程)

为了说明这个场景,我在actor中使用了Thread.sleep的各种用法,运行了两个测试。我发现它可以使用大约10个线程(如果没有进行睡眠调用)到最多80个线程(如果我调用睡眠1秒)。这些测试是在一台8芯的机器上进行的

总之,您需要检查Akka使用的实现,以了解并行性是如何使用的,这就是我研究
ForkJoinPool
的原因。除了查看配置文件,然后检查特定的实现之外,我不认为您可以执行以下操作:(


我希望这能澄清问题的答案-最初我以为您想看看actor系统的dispatcher是如何配置的。

假设您有一个
ActorSystem
实例,您可以检查其配置中设置的值。这就是如何获得配置文件中设置的值的方法:

val system=ActorSystem()
val config=system.settings.config.getConfig(“akka.actor.default dispatcher”)
config.getString(“类型”)
config.getString(“执行者”)
config.getString(“吞吐量”)
config.getInt(“fork-join-executor.parallelism-min”)
config.getInt(“fork join executor.parallelism max”)
config.getDouble(“fork-join-executor.parallelism factor”)
我希望这会有所帮助。您也可以参考页面了解有关特定配置设置的更多详细信息

更新

我在Akka中挖掘了更多信息,以确切了解它用于您的设置的内容。正如您可能已经预料到的,它使用了
ForkJoinPool
。用于构建它的并行性如下所示:

object ThreadPoolConfig {
  ...
  def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int =
math.min(math.max((Runtime.getRuntime.availableProcessors * multiplier).ceil.toInt, floor), ceiling)
  ...
}

此函数在某些时候用于构建
ForkJoinExecutorServiceFactory

新ForkJoinExecutorServiceFactory(
验证(tf),
ThreadPoolConfig.scaledPoolSize(
config.getInt(“最小并行度”),
config.getDouble(“并行度因子”),
config.getInt(“最大并行度”),
异步模式)
无论如何,这就是用于创建
ForkJoinPool
的并行性,它实际上是的一个实例。现在我们必须问一下这个池使用了多少线程?简单的回答是,它将仅在需要时使用整个容量(在本例中为80个线程)

为了说明这个场景,我在actor内部运行了两个使用Thread.sleep的测试。我发现它可以使用大约10个线程(如果没有进行睡眠调用)到最多80个线程(如果我调用睡眠1秒)。这些测试是在一台有8个核的机器上进行的

总而言之,您需要检查Akka使用的实现,以了解并行性是如何使用的,这就是我查看
ForkJoinPool
的原因。除了查看配置文件,然后检查特定的实现之外,我不认为您可以执行以下操作:(


我希望这能澄清问题的答案-起初我以为您想看看actor系统的调度程序是如何配置的。

为了最大限度地提高并行度,所有actor需要同时处理一些消息。您确定应用程序中是这样吗

以下面的代码为例

object Test extends App {

  val system = ActorSystem()

  (1 to 80).foreach{ _ =>
    val ref = system.actorOf(Props[Sleeper])
    ref ! "hello"
  }
}

class Sleeper extends Actor {
  override def receive: Receive = {
    case msg =>
      //Thread.sleep(60000)
      println(msg)
  }
}

如果你考虑配置和8个内核,你会看到少量的线程被生成(4, 5?),因为消息的处理对于一些真正的并行性来说太快了。 相反,如果您让您的参与者CPU忙于取消对讨厌的

线程的注释。sleep
您将看到线程数将增加到80个。但是,这只会持续1分钟,之后线程将逐渐从池中退出

我想主要的诀窍是:不要认为每个演员都是在一个单独的线程上运行的,而是在一个动作上出现一条或多条消息的时候