0

I am trying to use a counter for detecting number of unique words in a text send over HTTP methods. As I need to ensure concurrency on the value of this counter, I have changed it to AtomicInteger.

In certain cases I would like to get the current value of the counter and reset it to zero. If I understand it correctly, I must not use get() and set(0) methods separately like this, but use the getAndUpdate() method, BUT! I do not know how to implement the IntUnaryOperator for this reset and if it is even possible to do that on Java 6 server.

Thank you.

public class Server {

  static AtomicInteger counter = new AtomicInteger(0);

  static class implements HttpHandler {

    @Override
    public void handle(HttpExchange spojeni) throws IOException {
      counter.getAndUpdate(???); 
    }
  }
}
Kit Ostrihon
  • 824
  • 2
  • 14
  • 36
  • 3
    Just use [getAndSet](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#getAndSet-int-) (instead of getAndUpdate). (But to answer your question more directly: the lambda would be `oldValue -> 0`. That is, "a lambda that takes an int called oldValue, ignores it, and just returns 0.") – yshavit May 25 '17 at 15:35
  • 1
    To atomically reset value you can use AtomicInteger `getAndSet(reset value)` – Rohan May 25 '17 at 15:39
  • Also, getAndUpdate is new in 1.8, so I'm not sure why you tagged `java-6` specifically? – yshavit May 25 '17 at 15:40
  • @yshavit Have you read the whole question? :) – Kit Ostrihon May 25 '17 at 15:45
  • Yes, I have. The only part that's java 6-related is the last clause of the last sentence, where you're asking if it's possible to use a method that was introduced in Java 8, on a server that only has Java 6. I'm not sure why you would think that might be possible, but it's not. :) As for the rest of it, you're right that you shouldn't use `get()` and `set(0)` separately, but it's totally fine to use the single, atomic operation `getAndSet(0)`. That's what it's there for. – yshavit May 25 '17 at 15:52
  • @yshavit Sorry, I haven't got a clue what method was introduced when. Thank you for your clarification. – Kit Ostrihon May 25 '17 at 16:20
  • 1
    Ah, okay -- that's fair enough. For future reference, Javadocs include a "since" tag, and the JDK classes are good about keeping it up to date. In this case, if you look at the docs for [updateAndGet](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html#updateAndGet-java.util.function.IntUnaryOperator-), you'll see it says "since 1.8." A less elegant trick (for third-party libraries with less scrupulous documentation) is to just look at the old version of the docs. In this case, the Java 7 docs for AtomicInteger don't have updateAndGet. – yshavit May 25 '17 at 16:24

2 Answers2

2

getAndUpdate() is basically for when you want to set the value based on some operation involving the previous value (for example, doubling the value). If the value you want to update to is always zero then getAndSet() is the more obvious choice. The getAndSet() operation is available in Java 6, so addresses your problem here.

As you don't have the lamba based atomic update operations available before Java 8, if you wanted to achieve something similar there you would either need to handle your own synchronization or use the compareAndSet() method, potentially retrying until success.

BarrySW19
  • 3,759
  • 12
  • 26
1

You can use getAndSet(int newValue)method

/**
     * Atomically sets to the given value and returns the old value.
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final int getAndSet(int newValue) {
        for (;;) {
            int current = get();
            if (compareAndSet(current, newValue))
                return current;
        }
    }

or you can use compareAndSet(int expect, int update) with related to initial value and you want to update new value

/**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return true if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }`
gati sahu
  • 2,576
  • 2
  • 10
  • 16