How to lock thread correctly with ReentrantLock or Mutex? Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of How to lock thread correctly with ReentrantLock or Mutex? without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I have an acync method with callback:

myAsyncMethod(params) {
    handleResult(it)
}

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

val result = mySyncMethod(params)
handleResult(result)

I can’t re-implement it by another way because this method provided by third-party library.

I am trying to use 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))

I wait that I should see 1, 2, 3, 4. But I get 1, 2, 4, 3 and null in handleResult. I am trying the same with mutex but with the same result. How to make it works?

P.S. Sure I can use synchronized, but in this case I have to use Object-variable additionally.

Answer

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

Then you misunderstood what ReentrantLock is actually for.

If mySyncMethod can be called from different threads, then after mutex.lock() is called, only one thread at a time can execute the code following mutex.lock() – the other threads executing this method have to wait. Once mutex.unlock() is called, one of the waiting threads will execute the code too and so on.

So, the thread owning the mutex forces the other threads to wait but its own flow isn’t blocked. myAsyncMethod starts running after the outer method has completed already and hence result is still null.

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

According to your requirements, you need to block the current thread until the async task is complete. To achieve this, you could use Semaphore or CountDownLatch. For example, with Semaphore, your method could look as follows:

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
}
We are here to answer your question about How to lock thread correctly with ReentrantLock or Mutex? - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji