首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检测方法的并发调用

检测方法的并发调用
EN

Stack Overflow用户
提问于 2014-05-18 16:30:23
回答 2查看 256关注 0票数 0

我有一个类序列化程序:

代码语言:javascript
复制
class Serializer<T> extends Consumer<T> {
    final Consumer<? super T> actual;
    // constructor omitted for brewity
    @Override public synchronized void accept(T t) {
         actual.accept(t);
    }
}

其目的是确保实际的线程一次从一个线程中运行。但是,在保持锁的同时调用回调通常是危险的,因此调用方不是持有锁,而是将传入的值排队,其中一个线程将进入,释放队列并依次调用循环中的实际使用者。(另一个限制是不知道并发呼叫者的数量。)

代码语言:javascript
复制
    final ConcurrentLinkedQueue<T> queue;
    final AtomicInteger wip;
    @Override public void accept(T t) {
        queue.offer(t);
        if (wip.getAndIncrement() == 0) {
            do {
                actual.accept(queue.poll());
            } while (wip.decrementAndGet() > 0);
        }
    }

这是可行的,并将无界队列、线程跳转和线程卡在循环中的问题置之不理,但与直接方法调用相比,基准测试在单线程情况下提供了10%的吞吐量。当I.用同步块实现这个排队/发射时,基准测试给出了50%的直接情况,因为JVM优化了同步化;这将是很棒的,但它也不会扩展。使用juc.Lock扩展,但遭受类似的单线程吞吐量下降与上述代码。如果我没有弄错,一旦JVM优化了同步,它仍然需要使用一些保护,以防再次并发调用该方法并将锁定放回。

我的问题是,如何使用锁、队列或其他序列化逻辑实现类似的效果,即,在没有并发调用的情况下,拥有一条廉价且快速的路径,而另一条路径则适用于同意的use情况,这样代码就可以扩展,并且对于单线程的使用也是快速的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-19 10:20:46

正如其他人所说的,synchronized已经为您提供了一个相当有效的工具。因此,使用不同的东西不应该被期望更好的性能所激励。

但是,如果你的意图不是像你在问题中所说的那样阻止打电话的人,那是合法的。(虽然这可能意味着与较低的表现生活)。

在查看使用队列和原子整数的尝试时,我首先看到的是,在没有挂起的项和没有其他使用者正在运行的情况下,可以绕过队列。在争用较低的情况下,这可能会减少开销:

代码语言:javascript
复制
final ConcurrentLinkedQueue<T> queue;
final AtomicInteger wip;
@Override public void accept(T t) {
  if(wip.compareAndSet(0, 1)) { // no contention?
    actual.accept(t);
    if(wip.decrementAndGet()==0) return; // still no contention
  }
  else {
    if(!queue.offer(t))
      throw new AssertionError("queue should be unbounded");
    if(wip.getAndIncrement() != 0) return; // other consumer running
  }
  do {
    actual.accept(queue.poll());
  } while (wip.decrementAndGet() > 0);
}
票数 1
EN

Stack Overflow用户

发布于 2014-05-18 17:26:29

这就是同步为您所做的。(除其他策略外,它还使用了偏置锁定)

如果你问的是,是否有一种更有效的方法来对数据进行一般的同步,那么如果你能想到这方面几十年的专业知识,我会感到非常惊讶。如果您确实找到了一种更快的方式,您可以出名,这可能是"kd304锁定策略“。

如果您是在问是否有方法减少特定/特殊情况下代码段的开销,那么肯定有,但这取决于您正在做什么,这在问题中并不清楚。

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

https://stackoverflow.com/questions/23724249

复制
相关文章

相似问题

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