java - 用单线程写 LMAX

标签 java multithreading rx-java disruptor-pattern lmax

我已经了解了 LMAX 和这个叫做 RingBuffer 的美妙概念。 所以人们告诉我们,当只用一个线程写入环形缓冲区时,性能比多个生产者要好得多......

但是我真的不觉得典型的应用程序可以只使用一个线程在环形缓冲区上写...我真的不明白 lmax 是怎么做到的(如果他们这样做的话)。例如N个不同的交易员在交易所下订单,这些都是异步请求转换为订单并放入ringbuffer,他们怎么可能用一个线程来写?

问题 1. 我可能遗漏了某些东西或误解了某些方面,但是如果您有 N 个并发生产者,如何将它们合并为 1 个而不相互锁定?

问题 2。我记得 rxJava observables,你可以使用 Observable.merge 将 N 个 observables 合并为 1 个我想知道它是否以任何方式阻止或维护任何锁?

最佳答案

多线程写入对 RingBuffer 的影响很小,但在非常重的负载下可能会很重要。

RingBuffer 实现包含一个 next 节点,下一次添加将在该节点进行。如果只有一个线程正在写入环,该过程将始终在最短时间内完成,即 buffer[head++] = newData

要在避免锁定的同时处理多线程,您通常会执行类似 while ( !buffer[head++].compareAndSet(null,newValue)){} 的操作。当其他线程干扰数据存储时,这个紧密循环将继续执行,从而降低吞吐量。

请注意,我在上面使用了伪代码,看看我的实现中的getFree here一个真实的例子。

  // Find the next free element and mark it not free.
  private Node<T> getFree() {
    Node<T> freeNode = head.get();
    int skipped = 0;
    // Stop when we hit the end of the list
    // ... or we successfully transit a node from free to not-free.
    // This is the loop that could cause delays under hight thread activity.
    while (skipped < capacity && !freeNode.free.compareAndSet(true, false)) {
      skipped += 1;
      freeNode = freeNode.next;
    }
    // ...
  }

关于java - 用单线程写 LMAX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30237952/

相关文章:

c# - Visual Studio 2008 .Net - 跨过当前进程

Android Espresso waitFor.. 和 Thread.sleep() 解决方案

java - 将 Spring Security 与线程池结合使用会导致重用线程时出现竞争条件

java - GSON 不区分大小写的枚举反序列化

java - 在 Spring MVC 中更正 JavaScript 文件中的 URL

java - Maven 多模块 Spring MVC 应用程序

java - 在cplex中输出二维变量数组

C++ 并发写入 bool 数组(不是 std::vector)

java - 使用多线程 RxJava 的响应式(Reactive)拉取

android - Retrofit 2 + Rxjava处理错误