Coroutines Android 4.1:后续启动阻塞队列后无法正常工作

时间:2018-05-15 10:07:00

标签: android kotlin blockingqueue kotlinx.coroutines

如果我运行的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)

为什么会发生这种情况以及如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

ArrayBlockingQueue.take操作阻止。它会阻止调用者线程,并且不允许将其用于其他任何内容。小&#34;小&#34;设备可能只有一个后台线程在默认线程池中,当你阻止这个线程时,没有其他任何有用的东西可以发生。协同程序旨在使用不阻塞线程的非阻塞(异步)API。

使用协同程序,您应该使用频道,它们与协同程序的用途大致相同,因为阻塞队列服务于线程。通道不会阻止调用程序线程,但挂起调用协同程序,从而允许对多个正在运行的协同程序使用相同的线程。

您可以在Guide to kotlinx.coroutines by example中找到有关频道的更多信息。