Mutex is locked by LOCKED but expected Thread


#1

I have this crucial problem where I have java stand-alone application. I need to request some parameter from web-service to my java application and after that my application send the same parameter to my smart meter. After sending params to the smart meter, my application needs to wait till the result came from the smart meter.

For the stand-alone application, I use jersey library. The jersey library reserve at-least 10 threads for processing the web services. You see I need to hold the specific the Thread for waiting for the result from the smart meter. For this specific problem, I create a MutexHolderCollection which holds the current thread.

Below is the MutexHolderCollection.

class MutexHolderCollection {

private val mutex = Mutex(true)
private val mutexHolders = mutableMapOf<String, Thread>()

fun blockThread(key: String, blockingThread: Thread) {
    if (!mutexHolders.contains(key)) {
        mutexHolders[key] = blockingThread
        runBlocking {
            mutex.withLock(blockingThread) { startTimer(blockingThread) }
        }
    }
    println("Mutex Complete")
}

private fun startTimer(blockingThread: Thread) {
    Observable.timer(1, TimeUnit.MINUTES)
            .subscribeOn(appRxSchedulers.network)
            .subscribe({
                blockThread(blockingThread)
            }, Throwable::printStackTrace)
}

fun unlockThread(key: String) {
    if (mutexHolders.contains(key)) {
        val blockingThread = mutexHolders[key]
        mutex.unlock(blockingThread)
    }
}

private fun blockThread(blockingThread: Thread) = mutex.unlock(blockingThread)

}

Now I’m successfully able to lock the thread but when I’m trying to unlock it gives me this exception.

The Mutex is locked by LOCKED but expected Thread[Grizzly(8),5, main].

Do someone have any idea to solve this problem.

Thank you for your time…


#2

Have you tried:

fun blockThread(key: String, blockingThread: Thread) {
    if (!mutexHolders.contains(key)) {
        mutexHolders[key] = blockingThread
        runBlocking {
            mutex.withLock { startTimer(blockingThread) }
        }
    }
    println("Mutex Complete")
}

fun unlockThread(key: String) {
    if (mutexHolders.contains(key)) {
        val blockingThread = mutexHolders[key]
        mutex.unlock()
    }
}

?

According to the documentation the owner parameter is optional and for debugging purposes only:
Mutex.unlock documentation
Mutex.withLock documentation


#3

@forinil2 By using the below approach I’m unable to stop the specific thread. This approach is only used to stop the current thread.

fun blockThread(key: String, blockingThread: Thread) {
if (!mutexHolders.contains(key)) {
    mutexHolders[key] = blockingThread
    runBlocking {
        mutex.withLock { startTimer(blockingThread) }
    }
}
println("Mutex Complete")

}


#4

I see. I browsed the source code of the Mutex interface and its implementation, and it seem that this line:

private val mutex = Mutex(true)

sets the owner to LOCKED, so maybe try changing it to:

private val mutex = Mutex(false)

therefore letting Mutex.withLock set the owner.


#5

@forinil2 By setting the Mutex(false). The mutex instance is unable to lock the thread.