有没有一个好方法来实现synchronized关键字的异步版本?显然,synchronized()关键字会频繁阻塞当前线程。例如:
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;
}
}我可以从这个块返回一个布尔值-它是同步的。有没有一种异步的方式呢?
如下所示:
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);
});
}我创建了Object.onLockAcquisition方法,但是寻找类似的东西。
发布于 2019-02-07 22:51:09
你有没有研究过其他选择?根据你想要实现的目标,下面的一个--或者组合--可能会有帮助(也可能没有):
(使用队列执行程序使用单线程执行器执行临界区)
发布于 2019-02-09 22:50:55
就Vert.x而言,正确的解决方案是使用SharedData.getLock()
原因是异步是特定库的一部分,而不是JVM平台的一部分。
除非Vert.x在集群模式下运行,否则它将回退到本地锁:
public void getLockWithTimeout(String name, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
...
if (clusterManager == null) {
getLocalLock(name, timeout, resultHandler);
} else {
...
}
}getLock在下面使用LocalAsyncLocal:
localAsyncLocks.acquire(vertx.getOrCreateContext(), name, timeout, resultHandler);acquire()在幕后使用ConcurrentHashMap.compute:https://github.com/eclipse-vertx/vert.x/blob/master/src/main/java/io/vertx/core/shareddata/impl/LocalAsyncLocks.java#L91
因此,如果你真的想要有自己的实现,你可以从上面的代码中获得灵感。
发布于 2019-02-07 17:26:34
Vertx中的一种解决方案是工具包的异步锁定调用:
https://vertx.io/docs/vertx-core/java/#_asynchronous_locks
看起来是这样的:
sd.getLock("mylock", res -> {
Lock lock = res.result();
vertx.setTimer(5000, tid -> lock.release());
});然而,这并不是我真正想要的解决方案,因为这是一个网络锁,这意味着与正常的内存锁相比,它相当慢。我只需要在单个线程中创建一个锁,而不是跨线程或进程。
https://stackoverflow.com/questions/54568507
复制相似问题