Personal notes.
When I was researching Java exclusive control, I found the following article.
Java synchronized does not guarantee order.
As mentioned in the article, locking with synchronized
does not guarantee the release order when multiple locks are locked at the same time.
If you don't understand it, you're likely to get stuck in some places.
Our workaround is to replace the locking mechanism from synchronized
to java.util.concurrent.locks.ReentrantLock
.
//The constructor is fair=Specify with true
//Lock instance is used between threads that are exclusively controlled
ReentrantLock lock = new ReentrantLock(true);
try {
lock.lock();
//Processing during exclusive control
} finally {
lock.unlock();
}
I can achieve the purpose even if I use it as it is. Unlike synchronized
, it requires explicit lock release, and if it is inadvertently leaked, it can lead to a serious situation.
So I created a wrapper for ReentrantLock and forced it to use locks and unlocks in pairs.
FairLock.java
public class FairLock {
private ReentrantLock lock = new ReentrantLock(true);
public void withSync(FairSyncTask task) {
try {
lock.lock();
task.act();
} finally {
lock.unlock();
}
}
public interface FairSyncTask {
void act();
}
}
Example of use
//Example written in synchronized
private final Object syncObj = new Object();
public void actWithUnfair() {
synchronized(syncObj) {
//Processing during exclusive control
}
}
//Example replaced with ReentrantLock wrapper
private final FairLock fairLock = new FairLock();
public void actWithFair() {
fairLock.withSync(() -> {
//Processing during exclusive control
});
}
I wonder if I knew it. I hope this article helps someone.