首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >synchronized()的异步(非阻塞)版本{}

synchronized()的异步(非阻塞)版本{}
EN

Stack Overflow用户
提问于 2019-02-07 15:44:10
回答 3查看 929关注 0票数 10

有没有一个好方法来实现synchronized关键字的异步版本?显然,synchronized()关键字会频繁阻塞当前线程。例如:

代码语言:javascript
复制
  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;
    }

  }

我可以从这个块返回一个布尔值-它是同步的。有没有一种异步的方式呢?

如下所示:

代码语言:javascript
复制
  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方法,但是寻找类似的东西。

EN

回答 3

Stack Overflow用户

发布于 2019-02-07 22:51:09

你有没有研究过其他选择?根据你想要实现的目标,下面的一个--或者组合--可能会有帮助(也可能没有):

  • 双重锁定替代方案(使用volatile +监视和检查volatile两次,一次在锁定之前,一次在锁定之后)
  • 使用AtomicXXX和那里的compareAndSet/compareAndExchange等。methods
  • use the java.util.concurrent.locks
  • use a single threaded executor to execute the critical section
  • use a queue

(使用队列执行程序使用单线程执行器执行临界区)

票数 6
EN

Stack Overflow用户

发布于 2019-02-09 22:50:55

就Vert.x而言,正确的解决方案是使用SharedData.getLock()

原因是异步是特定库的一部分,而不是JVM平台的一部分。

除非Vert.x在集群模式下运行,否则它将回退到本地锁:

代码语言:javascript
复制
public void getLockWithTimeout(String name, long timeout, Handler<AsyncResult<Lock>> resultHandler) {
    ...
    if (clusterManager == null) {
      getLocalLock(name, timeout, resultHandler);
    } else {
      ...
    }
  }

getLock在下面使用LocalAsyncLocal

代码语言:javascript
复制
localAsyncLocks.acquire(vertx.getOrCreateContext(), name, timeout, resultHandler);

acquire()在幕后使用ConcurrentHashMap.computehttps://github.com/eclipse-vertx/vert.x/blob/master/src/main/java/io/vertx/core/shareddata/impl/LocalAsyncLocks.java#L91

因此,如果你真的想要有自己的实现,你可以从上面的代码中获得灵感。

票数 6
EN

Stack Overflow用户

发布于 2019-02-07 17:26:34

Vertx中的一种解决方案是工具包的异步锁定调用:

https://vertx.io/docs/vertx-core/java/#_asynchronous_locks

看起来是这样的:

代码语言:javascript
复制
sd.getLock("mylock", res -> {
   Lock lock = res.result();
   vertx.setTimer(5000, tid -> lock.release());
});

然而,这并不是我真正想要的解决方案,因为这是一个网络锁,这意味着与正常的内存锁相比,它相当慢。我只需要在单个线程中创建一个锁,而不是跨线程或进程。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54568507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档