2

I would like to check from the unit test if the future is completed or cancelled and still not running in the background consuming cpu resources. One way is to check the number of futures before and after i start my test method. whats the best way to do this?

user2715182
  • 653
  • 2
  • 10
  • 23

1 Answers1

1

You can use something as simple as Thread.getAllStackTraces to get the threads and their states. scala Future will run on thread as well.

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"
      )
    })
  }
}

which will give the state of two threads spawn in above app,

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

Output:

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

You can instead use graphic tool like jmc (java mission control) and jconsole to see the running threads with their CPU usage and all.

prayagupa
  • 30,204
  • 14
  • 155
  • 192
  • Why is the quick task's state WAITING and never TERMINATED? I put some sleep before print the state using getAllStackTraces. I did a thread.join before print. But it is WAITING always – user2715182 Oct 14 '18 at 07:36
  • if you `jstack` you get more descriptive states, like `java.lang.Thread.State: WAITING (parking)` which means suspended and etc etc [Understanding java.lang.Thread.State: WAITING (parking)](https://stackoverflow.com/a/7498108/432903) – prayagupa Oct 18 '18 at 22:47