CountDownLatch不释放线程 [英] CountDownLatch not freeing thread
问题描述
我有一个方法,可以从Firebase Storage加载图像.它在后台线程中调用,我需要阻止它,直到加载图像为止(以避免回调地狱).这是代码(在Kotlin中)
I have a method, which loading image from Firebase Storage. It's called in background thread, and I need to block it, until image is loaded (to avoid callback hell). Here is the code (in Kotlin)
override fun fromNet(): Bitmap? {
Log.wtf(TAG, "$name loading from firebase")
var result: Bitmap? = null
val lock = CountDownLatch(1)
try {
FirebaseStorage.getInstance().getReferenceFromUrl(FIRE_STORAGE).child(ctx.getKGL().famkey)
.child(name).getBytes(524288L)
.addOnFailureListener {
Log.wtf(TAG, "$name load failure")
lock.countDown()
}
.addOnSuccessListener { bytes ->
Log.wtf(TAG, "$name loaded")
val b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64))
result = b
lock.countDown()
ctx.saveToCache(name, b)
}
.addOnCompleteListener {
Log.wtf(TAG, "on complete")
lock.countDown()
}
} catch (ignored: NullPointerException) { lock.countDown() }
lock.await()
return result
}
但是线程永远永远被阻塞
But thread stays blocked forever
Logcat:
A/MemberPhoto: xvd6z67gZfMCLG4c9mkGXKe9ML53 load failure
A/MemberPhoto: on complete
UPD:可能是因为Firebase代码是Java,而我的代码是在Kotlin中?
UPD: May the cause be, that Firebase code is Java, and my code is in Kotlin?
推荐答案
如果要确保lock.await()
不会使当前线程永远等待,则需要确保在发生任何情况时都调用lock.countDown()
.在这里,您应该在try/finally
块周围加上侦听器的代码,以便在finally
块中调用lock.countDown()
.
If you want to be sure that lock.await()
won't make your current thread wait forever, you need to ensure that lock.countDown()
is called whatever happens so here you should surround with a try/finally
block the code of your listeners in order to call lock.countDown()
within a finally
block.
实际上与您当前的代码有关,例如,如果BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64))
失败,则将永远不会调用lock.countDown()
,这将使调用lock.await()
的线程永远等待.
Indeed otherwise with your current code if for example BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64))
fails, lock.countDown()
will never be called which will make the thread calling lock.await()
wait forever.
例如,在成功的情况下,您的侦听器的代码应为:
.addOnSuccessListener { bytes ->
try {
Log.wtf(TAG, "$name loaded")
val b = BitmapFactory.decodeByteArray(bytes, 0, bytes.size).scale(ctx.dip(64))
result = b
} finally {
lock.countDown()
}
ctx.saveToCache(name, b)
}
这篇关于CountDownLatch不释放线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!