在 java 中,我常常使用以下的方式快速启动一个线程。
new Thread(() -> {
// do something
}).start();
然后到了 kotlin 里,我就习惯性的
thread {
// do something
}.start()
然后,它就炸了...
Caused by: java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:869)
我当场黑人问号,难道 kotlin 的线程不能用 java 的 start()
方法启动?这完全没道理啊?那为啥它要返回一个java.lang.Thread
的对象?
于是去翻了以下 kotlin thread 的源码,瞬时大悟。
public fun thread(
start: Boolean = true,
isDaemon: Boolean = false,
contextClassLoader: ClassLoader? = null,
name: String? = null,
priority: Int = -1,
block: () -> Unit
): Thread {
val thread = object : Thread() {
public override fun run() {
block()
}
}
if (isDaemon)
thread.isDaemon = true
if (priority > 0)
thread.priority = priority
if (name != null)
thread.name = name
if (contextClassLoader != null)
thread.contextClassLoader = contextClassLoader
if (start)
thread.start()
return thread
}
kotlin 的 thread 是一个函数,而不是一个对象。
(虽然 kotlin 调用函数和创建对象的语法是一样的,但是规范的命名要求 class 以大写字母开头命名)
它封装了Thread
的创建和一些参数的配置,并默认会在创建完成后 start()
这个线程,再返回Thread
对象。
也就是说,造成崩溃的原因在于:多次启动了同一个线程。
因此,在 kotlin 中,想要立即启动一个线程只需要:
thread {
// do something
}
如果不想立即启动这个线程,则可以选择传统的创建 Thread 对象,或者
val t = thread(false) {
// do something
}
// 需要时启动
t.start()
这波是语法糖太甜了。谢谢,有被毒到。