сбросить AtomicInteger в ноль, если он собирается переполнить потокобезопасным способом - PullRequest
0 голосов
/ 17 января 2019

У меня есть AtomicInteger, который увеличивается на несколько потоков.

Я хочу сбросить на ноль, если это AtomicInteger переполнено, но атомарным способом. Я хочу убедиться, что значение переменной counter всегда положительное, поэтому, как только clientCounter переполнится или будет переполнено, я сброслю этот AtomicInteger на ноль. Я пришел с кодом ниже, но я не уверен, что это потокобезопасно, потому что я делаю дополнение для проверки и сброса. Есть ли лучший способ сделать это?

  private static final AtomicInteger clientCounter = new AtomicInteger(0);

  // called by multiple threads
  public static int getCounter() {
    final int counter = clientCounter.incrementAndGet();

    // reset "clientCounter" to zero as soon as it overflow
    // basically I don't want "counter" value should be negative if it overflow
    // is below thread safe?
    if (counter + 1 < 0) {
      clientCounter.set(0);
    }

    if (counter % SIZE == 0) {
        // save counter in database
    }

    return counter;
  }

Обновление:

Ниже приведен мой метод, и я также использую значение newCounter для сохранения в базе данных. И строка, где я сохраняю в базе данных, просит сделать newCounter конечной переменной, и я не могу сделать newCounter конечной переменной здесь. Как это исправить сейчас?

  public static int getCounter() {
    int counter;
    int newCounter;
    do {
        counter = clientCounter.get();
        newCounter = counter < Integer.MAX_VALUE ? counter + 1 : 1;
    } while (!clientCounter.compareAndSet(counter, newCounter));

    if (newCounter % SIZE == 0) {
      Executors.newSingleThreadExecutor().execute(new Runnable() {
        @Override
        public void run() {
          // this is asking "newCounter" to make final
          DBClient.getInstance().save(newCounter);
        }
      });
    }

    return newCounter;
  }

1 Ответ

0 голосов
/ 17 января 2019

Если я правильно понимаю, я думаю, вам нужно compareAndSet для этого.

int counter;
int newCounter;
do {
    counter = clientCounter.get();
    newCounter = counter < Integer.MAX_VALUE ? counter + 1 : 1;
} while (!clientCounter.compareAndSet(counter, newCounter));
return newCounter;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...