我正在计算应用程序中的延迟(以毫秒为单位),我想将这些指标插入线程安全列表结构中。然后,我将使用该列表来计算平均值,中位数,第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);
}
好的,我不确定我是否所有规格都正确,但这是一种实现方法:
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] 删除。
我来说两句