我有一个带有回调的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:
根据您的要求,您需要阻塞当前线程,直到异步任务完成。为此,可以使用Semaphore或CountDownLatch。例如,使用
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/