How can we use AtomicInteger for limited sequence generation say the sequence number has to be between 1 to 60. Once the sequence reaches 60 it has to start again from 1. I wrote this code though not quite sure wether this is thread safe or not?
public int getNextValue()
{
int v;
do
{
v = val.get();
if ( v == 60)
{
val.set(1);
}
}
while (!val.compareAndSet(v , v + 1));
return v + 1;
}
An AtomicInteger is used in applications such as atomically incremented counters, and cannot be used as a replacement for an Integer . However, this class does extend Number to allow uniform access by tools and utilities that deal with numerically-based classes.
AtomicInteger class provides operations on underlying int value that can be read and written atomically, and also contains advanced atomic operations. AtomicInteger supports atomic operations on underlying int variable. It have get and set methods that work like reads and writes on volatile variables.
Integers are object representations of literals and are therefore immutable, you can basically only read them. AtomicIntegers are containers for those values. You can read and set them. Same as asigning a value to variable.
Creating an AtomicIntegerAtomicInteger atomicInteger = new AtomicInteger(); This example creates an AtomicInteger with the initial value 0 . If you want to create an AtomicInteger with an initial value, you can do so like this: AtomicInteger atomicInteger = new AtomicInteger(123);
You could do
return val.getAndIncrement() % 60;
Unless you're concerned with exceeding the integer max-value (2147483647). If that is a concern, you could have a look at the getAndIncrement
implementation:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
All you need to change is the int next...
line to something like:
int next = (current + 1) % 60;
Oops. This loops through 0->59. You needed 1->60, so add one to the return-value to get the desired result.
You can do this in a single line using Java 8.
AtomicInteger counter = new AtomicInteger();
public int getNextValue() {
return counter.updateAndGet(n -> (n >= 60) ? 1 : n + 1);
}
If you make the method synchronized
then it will be threadsafe as long as the val
is nowhere else accessed. The approach is however a bit cumbersome, I'd rewrite it as follows:
public synchronized int getNextValue() {
val.compareAndSet(60, 0); // Set to 0 if current value is 60.
return val.incrementAndGet();
}
This gives 1 until with 60 back inclusive. If you actually need 1 until with 59, then replace 60
by 59
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With