如何以原子方式在作为ConcurrentMap映射一部分的ConcurrentLinkedQueue中添加延迟?

约翰

我正在计算应用程序中的延迟(以毫秒为单位),我想将这些指标插入线程安全列表结构中。然后,我将使用该列表来计算平均值,中位数,第95个百分位数。所以我了一下,发现列表没有太多选择,所以我决定使用它ConcurrentLinkedQueue来存储线程安全的延迟。如果我应该为此使用其他更好的线程安全数据结构,请告诉我。

public class LatencyMetricHolder {
  private final ConcurrentLinkedQueue<Long> latenciesHolder = new ConcurrentLinkedQueue<>();

  private static class Holder {
    private static final LatencyMetricHolder INSTANCE = new LatencyMetricHolder();
  }

  public static LatencyMetricHolder getInstance() {
    return Holder.INSTANCE;
  }

  private LatencyMetricHolder() {}    

  public void addLatencies(long latency) {
    latenciesHolder.add(latency);
  }

  public ConcurrentLinkedQueue<Long> getLatenciesHolder() {
    return latenciesHolder;
  }
}

我正在调用addLatencies方法来填充多线程代码中的延迟。

现在,我想latenciesHolder每个processId都有一个String。这意味着我们也可以processId多次获得相同的消息,有时它是一个新消息processId,因此我需要以某种方式以线程安全的方式和原子的方式为此提取latenciesHolder队列processId并在该特定队列上添加延迟。

因此,我决定为此使用并发映射,如下所示,其中的key将是processId

private final Map<String, ConcurrentLinkedQueue<Long>> latenciesHolderByProcessId = Maps.newConcurrentMap();

由于我使用的是地图,因此我需要同步创建新ConcurrentLinkedQueue实例,这在Java 7中有点棘手,我想就像在Java 7上一样。

什么是从多个线程中以原子方式无争用地填充此映射的正确方法,并且我想使用并发集合而不是常规锁定(如果有的话)?

更新:

  public void add(String type, long latencyInMs) {
    ConcurrentLinkedQueue<Long> latencyHolder = latenciesHolderByProcessId.get(type);
    if (latencyHolder == null) {
      latencyHolder = Queues.newConcurrentLinkedQueue();
      ConcurrentLinkedQueue<Long> currentLatencyHolder =
          latenciesHolderByProcessId.putIfAbsent(type, latencyHolder);
      if (currentLatencyHolder != null) {
        latencyHolder = currentLatencyHolder;
      }
    }
    latencyHolder.add(latencyInMs);
  }
罗伯托·阿蒂亚斯(Roberto Attias)

好的,我不确定我是否所有规格都正确,但这是一种实现方法:

public class LatencyMetricHolder {

 HashMap<Integer, ConcurrentLinkedQueue<Long>> map = new HashMap<>();

 public void addLatency(int processID, long latency) {
    synchronized(map) {
      ConcurrentLinkedQueue<Long> q = map.get(processID);
      if (q == null) {
        q = new ConcurrentLinkedQueue<Long>()
        map.put(processID, q);
      }
    }
    q.add(latency)
  }

  public ConcurrentLinkedQueue<Long> getLatenciesHolder(int processID) {
    synchronized(map) {
      return map.get(processId);
    }
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何以编程方式在Android中编写粗体字符串的一部分?

如何以斜体获取df中列的一部分?

如何通过PHP在JSON添加@符号作为对象名的一部分

如何添加外部头盔作为我的头盔的一部分?

Firebase Realtime DB:作为原子更新的一部分删除节点

如何用熊猫中的字典映射列值的一部分?

如何在表格的一部分中添加百分比

如何计算在Python中作为列表一部分的集合的出现次数?

如何在Flask中返回图像作为GET请求响应的一部分?

如何在 mysql 中执行 IF 语句作为 SELECT 语句的一部分

是否可以延迟对作为函数调用一部分的表达式的求值?

休眠:如何基于作为关联映射一部分的外键列选择单个项目?

如何在React中为正文文本的一部分添加样式

将事件侦听器作为部分页面的一部分加载时,如何将其添加到表单中?

在Woocommerce中将新的运输方式作为插件的一部分

在 terraform 的网络模块中添加服务端点作为子网变量的一部分

基于列的一部分映射值

如何以降低的特权运行脚本的一部分?

带下划线的数字文字如何在Java中工作以及为什么将其作为jdk 1.7的一部分添加

如何在Paw中将文件作为多部分请求的一部分上载?

伪类(:: after)可以作为HTML标签的一部分添加吗?

添加自定义操作作为操作下拉列表 (AEF) 的一部分

作为Vue插件的一部分向Vuex存储添加变异

如何在 OCaml 中输出一个空元组作为函数的一部分?

作为结构调用的一部分,如何在一行中编写变量名称?

如何使Automapper映射另一个表的一部分的属性

Promise 作为 redux 状态的一部分

使用变量作为语句的一部分

块作为块的一部分