【发布时间】:2017-12-12 05:40:21
【问题描述】:
我有一个状态机 - 待处理和已完成 - AtomicLong(线程)。我需要以原子方式递减挂起和递增完成
private final AtomicLong pending = new AtomicLong();
private final AtomicLong completed = new AtomicLong();
void markComplete() {
this.pending.decrementAndGet();
this.completed.incrementAndGet();
}
我可以通过使用块进行同步来使这个原子化。但这似乎破坏了使用并发对象的使用。
synchronized void markComplete() {
this.pending.decrementAndGet();
this.completed.incrementAndGet();
}
我想知道是否有更好的方法来做到这一点?
谢谢你帮助我。
【问题讨论】:
-
一个只有两个原子语句的同步块在我看来并不是一个大的性能问题。你有什么问题?
-
这些值是否必须为
long?如果两个int值就足够了,您可以通过执行((long) completed) << 32 + pending将它们打包到long中。递增完成意味着添加 1L -
不需要按位运算来更新状态:
long current = this.pending.addAndGet(1L<<32-1); long currentCompleted = current >> 32; long currentPending = current & 0xffffffff;。更改共享状态后发生按位操作 -
简单地说 - 你不能。您需要
synchronized(或其他类型的锁)或将它们作为AtomicReference<Holder>的一部分,其中Holder封装了这两个值 -
但问题仍然存在——你能用
int代替吗?在前 32 位表示增量和后 32 位减量的意义上,您可能会使用LongAdder的肮脏技巧逃脱
标签: java concurrency atomic