如果当前值小于另一个值,则进行原子更新
Atomic update if current value is less than another value
我正在寻找类似 AtomicInteger
或 LongAddr
的东西,它将:
- 如果值小于
MAX
则递增,其中 MAX
是某个用户定义的值。
- Return 指示原子是否递增的值。
用例:
- 我有一个任务队列。
- 只有
MAX
个任务应该 运行 同时进行。
- 将新任务添加到队列时,如果正在进行的任务数少于
MAX
,我想 运行 它
我不能使用 AtomicInteger
或 LongAddr
的原因是它们只允许您与特定值而不是值范围进行比较。
澄清:我不希望解决方案实际执行任务。我的用例涉及将网络请求传递给 Jetty。它使用单个线程来驱动多个网络请求。任何启动 Executor
的解决方案都会使这个目的失败,因为这样我最终每个网络请求都有一个线程。
Andy Turner 但我发现此解决方案更具可读性。本质上,我们只需要 new Semaphore(MAX)
和 Semaphore.tryAcquire()
.
如果你深入研究 Semaphore
的源代码,你会发现实现与 Andy 的答案相似。
下面是一些示例代码:
Semaphore semaphore = new Semaphore(MAX);
// ... much later ...
public void addTask(Runnable task)
{
if (semaphore.tryAcquire())
task.run();
else
queue.add(task);
}
public void afterTaskComplete(Runnable task)
{
semaphore.release();
}
使用compareAndSet()
:
boolean incrementToTheMax(AtomicInteger atomicInt, int max) {
while (true) {
int value = atomicInt.get();
if (value >= max) {
// The counter has already reached max, so don't increment it.
return false;
}
if (atomicInt.compareAndSet(value, value+1)) {
// If we reach here, the atomic integer still had the value "value";
// and so we incremented it.
return true;
}
// If we reach here, some other thread atomically updated the value.
// Rats! Loop, and try to increment of again.
}
}
我正在寻找类似 AtomicInteger
或 LongAddr
的东西,它将:
- 如果值小于
MAX
则递增,其中MAX
是某个用户定义的值。 - Return 指示原子是否递增的值。
用例:
- 我有一个任务队列。
- 只有
MAX
个任务应该 运行 同时进行。 - 将新任务添加到队列时,如果正在进行的任务数少于
MAX
,我想 运行 它
我不能使用 AtomicInteger
或 LongAddr
的原因是它们只允许您与特定值而不是值范围进行比较。
澄清:我不希望解决方案实际执行任务。我的用例涉及将网络请求传递给 Jetty。它使用单个线程来驱动多个网络请求。任何启动 Executor
的解决方案都会使这个目的失败,因为这样我最终每个网络请求都有一个线程。
Andy Turner new Semaphore(MAX)
和 Semaphore.tryAcquire()
.
如果你深入研究 Semaphore
的源代码,你会发现实现与 Andy 的答案相似。
下面是一些示例代码:
Semaphore semaphore = new Semaphore(MAX);
// ... much later ...
public void addTask(Runnable task)
{
if (semaphore.tryAcquire())
task.run();
else
queue.add(task);
}
public void afterTaskComplete(Runnable task)
{
semaphore.release();
}
使用compareAndSet()
:
boolean incrementToTheMax(AtomicInteger atomicInt, int max) {
while (true) {
int value = atomicInt.get();
if (value >= max) {
// The counter has already reached max, so don't increment it.
return false;
}
if (atomicInt.compareAndSet(value, value+1)) {
// If we reach here, the atomic integer still had the value "value";
// and so we incremented it.
return true;
}
// If we reach here, some other thread atomically updated the value.
// Rats! Loop, and try to increment of again.
}
}