gpt4 book ai didi

java - Kotlin CoroutineDispatcher 创建额外的线程而不是重新抛出 RejectedExecutionException

转载 作者:行者123 更新时间:2023-11-30 05:36:21 25 4
gpt4 key购买 nike

这是一个例子:

// max 1 pending task in queue
val queue = LinkedBlockingQueue<Runnable>(1)
// max 1 thread / 1 active task
val executor = ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, queue)

val start = System.currentTimeMillis()
fun run() {
val millis = System.currentTimeMillis() - start
val thread = Thread.currentThread().name
println("executing after $millis ms on thread $thread")
Thread.sleep(3000)
}

executor.execute { run() }
executor.execute { run() }
// executor.execute { run() } // RejectedExecutionException, ok

Thread.sleep(10_000)

val job = SupervisorJob()
val dispatcher = executor.asCoroutineDispatcher()
val exceptionHandler = CoroutineExceptionHandler { _, _ ->
println("never invoked")
}

val scope = CoroutineScope(job + dispatcher + exceptionHandler)

scope.launch { run() }
scope.launch { run() }
scope.launch { run() } // !

最后一行导致创建一个新线程,而不是抛出RejectedExecutionException(或调用exceptionHandler):

3 毫秒后在线程 pool-1-thread-1 上执行
3006 毫秒后在 thread pool-1-thread-1 上执行
在 thread pool-1-thread-1 上 10063 毫秒后执行
在线程 kotlinx.coroutines.DefaultExecutor 上 10079 毫秒后执行
13066 毫秒后在 thread pool-1-thread-1 上执行

如果队列已满,上面的代码应该会失败,但我认为无法使用 Kotlin 协程正确实现它:使用自定义 RejectedExecutionHandler 抛出不同的异常有助于实现所需的行为但违反了 Executor/RejectedExecutionHandler 约定,并且可能会破坏其他代码。

最佳答案

Dispatcher 不是 Executor,并且具有非常不同的契约(Contract)和目的。特别是,不能调度协程的恢复。

类比Java线程,它相当于Thread.destroy(),它使线程消失得无影无踪。没有 finally block 被执行,没有 synchronized block 被退出,因为线程没有遇到任何使其完成的异常。 Thread.destroy() 已从 Java 中删除,这是有充分理由的。

请注意,没有可以向其抛出 RejectedExecutionException 的用户代码。您有一个非常狭窄的特殊情况,其中协程根本不暂停,它们只是开始。这是您与任务提交的类比似乎合理的唯一原因。

关于java - Kotlin CoroutineDispatcher 创建额外的线程而不是重新抛出 RejectedExecutionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56532550/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com