前言
最近在创建线程的时候写了如下代码,然后发现线程内的 run 方法总是无法执行:
object MyThread {
def thread(body: => Unit): Thread = {
val thread = new Thread {
override def run(): Unit = body
}
thread.start()
thread
}
def main(args: Array[String]): Unit = {
println("main thread start")
val t = thread(() => {
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} start ...")
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} is running ...")
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} new thread stop ...")
})
t.join()
println("main thread end")
}
}
输出:
main thread start
main thread end
Process finished with exit code 0
经过分析,主要是 thread 方法 body 参数的定义,使用,和传参使用不正确
=> Unit
=> Unit 类型代表的不是方法,代表的是个代码块,给该类型传参的时候虽然可以传递方法,但是由于该类型不能调用,所以参数也无法执行。但是传递一个代码块就可以。
def thread(body: => Unit): Thread = {
val thread = new Thread {
override def run(): Unit = body // 不能写成 body(),因为 => Unit 不支持
}
thread.start()
thread
}
在上面的示例中,body 是无法调用的。虽然可以传递一个 () => Unit 类型的方法给body, 但是由于无法调用,在这里也没有什么用。但是如果直接传递一个代码块,就没有影响:
thread({
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} start ...")
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} is running ...")
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} new thread stop ...")
})
() => Unit
() => Unit 相比前者好理解一些,就是一个无参方法。
def thread(body: () => Unit): Thread = {
val thread = new Thread {
override def run(): Unit = body() // 这里可以调用
}
thread.start()
thread
}
def main(args: Array[String]): Unit = {
println("main thread start")
val t = thread(() => { // 这路传递的是匿名方法,不再是代码块
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} start ...")
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} is running ...")
Thread.sleep(1000)
println(s"${Thread.currentThread().getName} new thread stop ...")
})
t.join()
println("main thread end")
}
需要注意的事这里并不能传递代码块。所以 () => Unit 可以传递给 => Unit 。 反过来不能,所以可以推断出 => Unit 也许是 () => Unit 的父类(实际上可能不是这样,这个可能和scala中函数的逆变和协变有关)