如果当前值小于另一个值

时间:2018-05-10 17:18:40

标签: java atomic

我正在寻找AtomicIntegerLongAddr之类的内容:

  • 如果值小于MAX,则增量,其中MAX是某个用户定义的值。
  • 返回一个值,指示原子是否增加。

使用情况:

  • 我有一系列任务。
  • 只有MAX个任务应该同时运行。
  • 将新任务添加到队列时,如果正在进行的任务数少于MAX
  • ,我想运行它

我无法使用AtomicIntegerLongAddr的原因是它们只允许您与特定值进行比较,而不是与值范围进行比较。

澄清:我不希望解决方案实际执行任务。我的用例涉及将网络请求传递给Jetty。它使用单个线程来驱动多个网络请求。任何触发Executor的解决方案都会失败,因为那样每个网络请求最终会有一个线程。

2 个答案:

答案 0 :(得分:2)

使用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.
  }
}

答案 1 :(得分:1)

Andy Turner provided an excellent answer但我觉得这个解决方案更具可读性。基本上,我们所需要的只是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();
}