我有此代码段,在线程完成后,我在其中检查线程的状态。
import java.lang.management.ManagementFactory
import scala.concurrent.ExecutionContext
import scala.collection.JavaConversions._
import scala.collection.JavaConverters.asScalaSetConverter
import scala.concurrent.duration.{Duration, SECONDS}
object ThreadUsage2 {
def main(args: Array[String]): Unit = {
println("Main thread" + Thread.currentThread().getName())
val ex = ExecutionContext.Implicits.global
var threadName = ""
val sleepTask = new Thread(() => {
threadName = Thread.currentThread().getName()
println("Executing Thread task :" + Thread.currentThread().getName())
Thread.sleep(5000)
println("Thread finished :" + Thread.currentThread().getName())
})
ex.execute(sleepTask)
sleepTask.join()
Thread.sleep(10000)
println("Now the sleep task is in state" + sleepTask.getState)
val running = Thread.getAllStackTraces.keySet()
running.asScala.toSet[Thread].foreach(a => {
if (a.getName.matches(threadName)) {
println(" thread with name " + threadName + " is in state " + a.getState)
}
})
}
}
我看到的输出令人困惑。我希望线程处于TERMINATED状态。我在两个印刷品中看到了两个不同的状态。 输出:
Main threadmain
Executing Thread task :scala-execution-context-global-12
Thread finished :scala-execution-context-global-12
Now the sleep task is in stateNEW
thread with name scala-execution-context-global-12 is in state TIMED_WAITING
出现上述线程状态的原因是什么?
答案 0 :(得分:2)
@Yaneeve已诊断出问题:您的sleepTask
线程从未真正启动。
但是为什么join
返回尚未开始的Thread
?
javadoc对此进行了解释。
此实现使用以
this.wait
为条件的this.isAlive
调用循环。当线程终止时,将调用this.notifyAll
方法。建议应用程序不要在线程实例上使用wait
,notify
或notifyAll
。
由于线程启动时isAlive
首先成为true
,因此上述含义意味着“加入”尚未启动的线程将立即成功。这种(种类)与javadoc的前一句矛盾,该句指出:
此线程死亡最多等待
millis
毫秒。
但是很明显,这就是实现的行为方式...
答案 1 :(得分:1)
execute
收到Runnable
:
/** Runs a block of code on this execution context.
*
* @param runnable the task to execute
*/
def execute(runnable: Runnable): Unit
因此执行者只关心您提供的代码块:
() => {
threadName = Thread.currentThread().getName()
println("Executing Thread task :" + Thread.currentThread().getName())
Thread.sleep(5000)
println("Thread finished :" + Thread.currentThread().getName())
}
那是因为Thread
是 Runnable
class Thread implements Runnable
因此,sleepTask.join()
是即时的,因为您创建的线程从未处于活动状态,因为您从未启动过它。
显然,将ex.execute(sleepTask)
更改为sleepTask.start()
会得到您所期望的TERMINATED
状态,但是我感觉这并不是您最初想要做的事情>