You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中可靠取消协程或线程的方法(含readln()阻塞场景)

Linux下Kotlin实现Boggle可中断定时器方案

核心问题是JVM的readln()是阻塞式IO,会卡住协程/线程,而且没法被中断。结合Linux环境,给你两个简单可行的方案:

方案一:非阻塞输入检测+协程

利用System.in.available()检查输入缓冲区是否有字符,搭配协程实现无阻塞的按键检测,同时定时器正常运行:

import kotlinx.coroutines.*

fun main() = runBlocking {
    // 启动定时器协程:5秒后提示时间到
    val timerJob = launch {
        delay(5000)
        println("\n时间到!")
        print('\u0007') // 播放系统提示音
    }

    // 启动输入检测协程:循环检查按键输入
    val inputJob = launch {
        while (true) {
            // 检查是否有按键输入(缓冲区有字节)
            if (System.in.available() > 0) {
                System.in.read() // 读取按键字符(无需等回车)
                println("\n提前终止!")
                timerJob.cancel() // 取消定时器
                break
            }
            delay(100) // 短暂休眠,避免CPU空转
        }
    }

    // 等待任一任务完成,结束程序
    joinAll(timerJob, inputJob)
}

注意:Linux终端默认是「规范模式」,按键会缓存到回车才提交给程序。所以上面的代码在默认终端下,还是需要按回车才能触发中断。要解决这个问题,需要临时修改终端模式。

方案二:修改终端模式+非阻塞检测

通过stty命令修改终端为非规范模式,让按键立即提交,无需等待回车:

import kotlinx.coroutines.*
import java.lang.Runtime.getRuntime

fun main() = runBlocking {
    // 修改终端为非规范模式:按键立即提交,无需回车
    getRuntime().exec("stty -icanon min 1").waitFor()

    try {
        val timerJob = launch {
            delay(5000)
            println("\n时间到!")
            print('\u0007')
        }

        val inputJob = launch {
            while (true) {
                if (System.in.available() > 0) {
                    System.in.read()
                    println("\n提前终止!")
                    timerJob.cancel()
                    break
                }
                delay(100)
            }
        }

        joinAll(timerJob, inputJob)
    } finally {
        // 程序结束后必须恢复终端规范模式,否则终端会异常
        getRuntime().exec("stty icanon").waitFor()
    }
}

为什么之前的方案失败?

  • 协程方案中readln()是阻塞式IO,会占用整个线程,导致定时器协程无法调度执行;
  • 线程方案中Thread.interrupt()无法打断readln()这类IO阻塞操作,而Thread.stop()已废弃且不安全。

内容的提问来源于stack exchange,提问作者ArrayBolt3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 20:42:19