android - 如何使用ReentrantLock或Mutex正确锁定线程?

标签 android kotlin

我有一个带有回调的acync方法:

myAsyncMethod(params) {
    handleResult(it)
}

我需要像这样将其转换为同步方法(阻止并返回结果):
val result = mySyncMethod(params)
handleResult(result)

我无法通过其他方式重新实现它,因为该方法由第三方库提供。

我正在尝试使用ReentrantLock:
fun mySyncMethod(params:Type) {
    Log.d("tag", "1")
    val result = null
    val mutex = ReentrantLock()
    myAsyncMethod(params) {
        Log.d("tag", "3")
        result = it
        mutex.unlock()
    }
    Log.d("tag", "2")
    mutex.lock()
    Log.d("tag", "4")
    return result
}

handleResult(mySyncMethod(params))

我等待,我应该看到1、2、3、4。但是我在handleResult中得到了1、2、4、3和null。我正在尝试使用互斥锁,但结果相同。如何使其运作?

附言当然可以使用同步,但是在这种情况下,我必须另外使用对象变量。

最佳答案

I expect that I should see 1, 2, 3, 4.



然后,您会误解ReentrantLock的实际用途。

如果可以从不同的线程调用mySyncMethod,则在调用mutex.lock()之后,一次只有一个线程可以执行mutex.lock()之后的代码-其他执行此方法的线程必须等待。一旦调用mutex.unlock(),等待线程之一也将执行该代码,依此类推。

因此,拥有mutex的线程会强制其他线程等待,但其自身的流不会被阻塞。 myAsyncMethod在外部方法已经完成之后开始运行,因此result仍然是null

I need to convert it to sync method (block and return result) like this:



根据您的要求,您需要阻塞当前线程,直到异步任务完成。为此,可以使用SemaphoreCountDownLatch。例如,使用Semaphore,您的方法如下所示:
fun mySyncMethod(params:Type) {
    Log.d("tag", "1")
    val result = null
    val semaphore = Semaphore(0)
    myAsyncMethod(params) {
        Log.d("tag", "3")
        result = it
        semaphore.release()
    }
    Log.d("tag", "2")
    semaphore.acquireUninterruptibly()
    Log.d("tag", "4")
    return result
}

关于android - 如何使用ReentrantLock或Mutex正确锁定线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60218696/

相关文章:

java - 找不到 android.support.v7.widget.CardView(Android Studio 1.1 预览版)

android - 如何在 Android 平台上使用 TensorFlow?

java - Android 应用程序滑动 viewpager 和滚动 recyclerview 非常慢,如何查明原因?

kotlin - 用字符串中的多个字符替换多个字符

kotlin - 如何在Intellij中配置Kotlin SDK外部文档?

android - 如何将启动屏幕 Activity 中获取的数据发送到 Kotlin 中的其他 Activity?

java - 如何让另一个类知道单击了按钮(Android Studio)

android - 从github导入项目时发生Gradle错误

kotlin - 检查映射是否包含子字符串。 Kotlin

java - 如何使用 gradle 启动交互式 Java 应用程序