首页 > 解决方案 > 在执行上下文中获得在后台运行的期货数量的最佳方法是什么?

问题描述

我想从单元测试中检查未来是否已完成或取消并且仍然没有在后台运行消耗 cpu 资源。一种方法是在我开始测试方法之前和之后检查期货的数量。最好的方法是什么?

标签: scala

解决方案


您可以使用简单的方法Thread.getAllStackTraces获取线程及其状态。scalaFuture也将在线程上运行。

import java.lang.management.ManagementFactory

import scala.concurrent.ExecutionContext

object ThreadUsage {

  def main(args: Array[String]): Unit = {
    val ex = ExecutionContext.Implicits.global

    ex.execute(new Thread(() => {
      println("executing timed task")
      Thread.sleep(2000)
    }))

    // equivalent Future {}
    // import scala.concurrent.Future
    // Future {
    //  println("executing timed task")
    //  Thread.sleep(2000)
    // } (ex)

    ex.execute(new Thread(() => {
      println("executing quick task")
    }))

    val running = Thread.getAllStackTraces.keySet()
    running.forEach(a => {
      val bean = ManagementFactory.getThreadMXBean
      println(a.getThreadGroup + "   " + 
              a.getName + "   " + 
              a.getState + "   " +   
              (bean.getCurrentThreadCpuTime / (1000 * 1000)) + "ms"
      )
    })
  }
}

这将在上面的应用程序中产生两个线程的状态,

  • scala-execution-context-global-12
  • scala-execution-context-global-14

输出:

executing timed task
executing quick task
java.lang.ThreadGroup[name=main,maxpri=10]   scala-execution-context-global-14   WAITING   528ms
java.lang.ThreadGroup[name=system,maxpri=10]   Reference Handler   WAITING   528ms
java.lang.ThreadGroup[name=main,maxpri=10]   Monitor Ctrl-Break   RUNNABLE   528ms
java.lang.ThreadGroup[name=main,maxpri=10]   main   RUNNABLE   528ms
java.lang.ThreadGroup[name=main,maxpri=10]   scala-execution-context-global-12   TIMED_WAITING   528ms
java.lang.ThreadGroup[name=system,maxpri=10]   Signal Dispatcher   RUNNABLE   528ms
java.lang.ThreadGroup[name=system,maxpri=10]   Finalizer   WAITING   528ms

您可以改为使用jmc(java 任务控制)之类的图形工具,并jconsole查看正在运行的线程及其 CPU 使用率等。


推荐阅读