如果我运行的launch
阻塞了阻塞队列,那么之后就不会运行其他launch
。这只发生在Android 4.1上,我用Android 6.0.1和7.0测试的其他设备工作得很好。这是一个例子:
class MainActivity : AppCompatActivity() {
private val blockingQueue = ArrayBlockingQueue<String>(10)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launch {
Log.d(javaClass.simpleName, "TEST 1")
}
launch {
blockingQueue.take().run {
Log.d(javaClass.simpleName, "TEST 2")
}
}
launch {
Log.d(javaClass.simpleName, "TEST 3")
}
}
}
输出:
05-15 12:09:39.707 4337-4361/org.testcoroutines D/StandaloneCoroutine: TEST 1
永远不会记录 TEST 3
。但是,如果我更换&#34;阻止&#34; launch
thread
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launch {
Log.d(javaClass.simpleName, "TEST 1")
}
launch {
blockingQueue.take().run {
Log.d(javaClass.simpleName, "TEST 2 $this")
}
}
launch {
Log.d(javaClass.simpleName, "TEST 3")
}
thread {
Thread.sleep(2000)
Log.d(javaClass.simpleName, "TEST WAKE UP")
blockingQueue.put("WAKE UP!")
}
}
,有效。
如果我通过在其上放置一个元素来解锁队列,其余的启动现在就会运行。
05-15 12:10:33.367 4471-4492/org.testcoroutines D/StandaloneCoroutine: TEST 1
05-15 12:10:35.387 4471-4493/org.testcoroutines D/MainActivity: TEST WAKE UP
05-15 12:10:35.387 4471-4492/org.testcoroutines D/String: TEST 2 WAKE UP!
05-15 12:10:35.387 4471-4492/org.testcoroutines D/StandaloneCoroutine: TEST 3
输出:
myGlTextureView.getBitmap(int width, int height)
为什么会发生这种情况以及如何解决这个问题?
答案 0 :(得分:2)
ArrayBlockingQueue.take
操作阻止。它会阻止调用者线程,并且不允许将其用于其他任何内容。小&#34;小&#34;设备可能只有一个后台线程在默认线程池中,当你阻止这个线程时,没有其他任何有用的东西可以发生。协同程序旨在使用不阻塞线程的非阻塞(异步)API。
使用协同程序,您应该使用频道,它们与协同程序的用途大致相同,因为阻塞队列服务于线程。通道不会阻止调用程序线程,但挂起调用协同程序,从而允许对多个正在运行的协同程序使用相同的线程。
您可以在Guide to kotlinx.coroutines by example中找到有关频道的更多信息。