max 的线程安全实现
我需要为网络服务器实现全局对象收集统计信息。我有 Statistics
单例,它有方法 addSample(long example)
,随后调用 updateMax
。这显然必须是线程安全的。我有这种方法来更新整个统计数据的最大值:
AtomicLong max;
private void updateMax(long sample) {
while (true) {
long curMax = max.get();
if (curMax < sample) {
boolean result = max.compareAndSet(curMax, sample);
if (result) break;
} else {
break;
}
}
}
这个实现正确吗?我正在使用 java.util.concurrent,因为我相信它会比简单的synchronized
更快。还有其他/更好的方法来实现这个吗?
I need to implement global object collecting statistics for web server. I have Statistics
singleton, which has method addSample(long sample)
, which subsequently call updateMax
. This has to be obviously thread-safe. I have this method for updating maximum of whole Statistics:
AtomicLong max;
private void updateMax(long sample) {
while (true) {
long curMax = max.get();
if (curMax < sample) {
boolean result = max.compareAndSet(curMax, sample);
if (result) break;
} else {
break;
}
}
}
Is this implementation correct? I am using java.util.concurrent, because I believe it would be faster than simple synchronized
. Is there some other / better way to implement this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
从 Java 8 开始,LongAccumulator 已介绍。
建议作为
您可以按如下方式使用它:
As of Java 8, LongAccumulator has been introduced.
It is advised as
You can use it as follows:
我认为这是正确的,但为了清楚起见,我可能会稍微重写一下,并且肯定添加注释:
编辑:通常我至少首先尝试同步版本,并且只有当我发现这种无锁代码引起问题时才使用它。
I think it's correct, but I'd probably rewrite it a little for clarity, and definitely add comments:
EDIT: Usually I'd at least try the synchronized version first, and only go for this sort of lock-free code when I'd found that it was causing a problem.
使用 Java 8,您可以利用函数式接口和简单的 lamda 表达式,只需一行代码即可解决此问题,无需循环:
该解决方案使用
updateAndGet(LongUnaryOperator)
方法。当前值包含在curMax
中,如果样本值大于当前最大值,则使用条件运算符执行简单测试,用样本值替换当前最大值。With Java 8 you can take advantage of functional interfaces and a simple lamda expression to solve this with one line and no looping:
The solution uses the
updateAndGet(LongUnaryOperator)
method. The current value is contained incurMax
and using the conditional operator a simple test is performed replacing the current max value with the sample value if the sample value is greater than the current max value.就好像您没有选择答案一样,这是我的:
它与接受的答案或多或少相同,但不使用
break
或while(true)
我个人不喜欢这一点。编辑:刚刚在java 8中发现了
DoubleAccumulator
。文档甚至说这是针对像您这样的汇总统计问题:as if you didn't have your pick of answers, here's mine:
it's more or less the same as the accepted answer, but doesn't use
break
orwhile(true)
which I personally don't like.EDIT: just discovered
DoubleAccumulator
in java 8. the documentation even says this is for summary statistics problems like yours:我相信你所做的是正确的,但这是一个更简单的版本,我也认为是正确的。
I believe what you did is correct, but this is a simpler version that I also think is correct.