Is there a good way to implement an asynchronous version of synchronized keyword? Obviously the synchronized() keyword will frequently block the current thread. For example:
public static boolean getLockSync(Runnable r) {
if (isLocked) {
r.run();
return true;
}
synchronized (My.lock) { // this is blocking, could block for more than 1-2 ms
isLocked = true;
r.run();
isLocked = false;
return false;
}
}
I can return a boolean from this block - it's synchronous. Is there a way to do this asynchronously?
Something like this:
public static void getLockAsync(Runnable r) {
if (isLocked) {
CompletableFuture.runAsync(r);
return;
}
Object.onLockAcquisition(My.lock, () -> { // this is non-blocking
isLocked = true;
r.run();
isLocked = false;
Object.releaseLock(My.lock);
});
}
I made up the Object.onLockAcquisition method, but looking for something like that.
The correct solution in terms of Vert.x would be to use SharedData.getLock()
Reason for that is that asynchronicity is part of a specific library, and not of JVM platform.
Unless Vert.x runs in a clustered mode, it will fall back to local lock:
public void getLockWithTimeout(String name, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
...
if (clusterManager == null) {
getLocalLock(name, timeout, resultHandler);
} else {
...
}
}
getLock
uses LocalAsyncLocal
underneath:
localAsyncLocks.acquire(vertx.getOrCreateContext(), name, timeout, resultHandler);
acquire()
uses ConcurrentHashMap.compute
under the hood:
https://github.com/eclipse-vertx/vert.x/blob/master/src/main/java/io/vertx/core/shareddata/impl/LocalAsyncLocks.java#L91
So if you really want to have your own implementation, you can take inspiration from the code above.
Have you investigated alternatives? Depending what you're trying to achieve then one - or a combination - of the following might help (or not):
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With