1

迁移到 Kotlin 1.5 后,我偶然发现了 Channel 的新trySendBlocking()方法存在问题。

所以,我们有一个演员返回 a SendChannel<Command>Command作为我们自己的数据类。

在 Kotlin 1.4 中向 actor 发送命令时,我们曾经像这样使用它的通道:

channel.sendBlocking(command)

现在,建议在 Kotlin 1.5 中使用以下内容:

channel.trySendBlocking(command)

很好,但是我想知道为什么不使用trySend()而不是trySendBlocking()?有些事情让我摸不着头脑:

  1. 如果我们确定通道的容量足够大,并且参与者消耗它的速度足够快,那么通道就不会被填满,并且trySend()总是会成功。我们可以做这样的事情来解决通道可能已满的少数情况:

    do { val result = channel.trySend(command) } while (result.isFailure)

  2. 内部trySendBlocking()使用runBlocking()阻塞整个线程。根据文档,runblocking()旨在将常规阻塞代码与以挂起样式编写的库连接起来,用于主要功能和测试”。但是这里它的使用方式超出了这个记录的用例。它可能会阻塞整个线程。我会认为这是一个坏主意?

  3. trySend()线程安全吗?如果多个线程trySend()在同一个通道上同时调用,会不会有麻烦?这就是我们喜欢的原因trySendBlocking()吗?

谢谢

4

1 回答 1

0
  1. 也许您想改用 send() 方法?

  2. 据我了解,这正是作者的意思。此方法是同步的,应与阻塞代码一起使用。如果它不可用,要将同步代码与异步桥接,您将使用 runBlocking 方法。

  3. 快速查看内部后,对我来说看起来像是线程安全的;它使用原子变量和其他与并发相关的东西,但作为不是这些的设计者,我无法确定。Actor应该是线程安全的。

于 2021-06-03T23:37:32.827 回答