在 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()

这波是语法糖太甜了。谢谢,有被毒到。