I have already asked this before how to generate auto increment ID Generate auto increment number by using Java.
I have used below code:
private static final AtomicInteger count = new AtomicInteger(0);
uniqueID = count.incrementAndGet();
The previous code working fine but the problem is count static variable. For this static its never start to 0 again, its always start with the last increment id. That is the issue.
Is there any alternative way except AtomicInteger?
Another issue is that I am working on GWT so AtomicInteger is not available in GWT.
So I have to find another way to do that.
AtomicInteger is a "signed" integer. It will increase till Integer.MAX_VALUE; then, due to integer overflow, you expect to get Integer.MIN_VALUE.
Unfortunately, most of the thread safe methods in AtomicInteger are final, including incrementAndGet(), so you cannot override them.
But you could create a custom class that wraps an AtomicInteger and you just create synchronized methods according to your needs. For instance:
public class PositiveAtomicInteger {
private AtomicInteger value;
//plz add additional checks if you always want to start from value>=0
public PositiveAtomicInteger(int value) {
this.value = new AtomicInteger(value);
}
public synchronized int incrementAndGet() {
int result = value.incrementAndGet();
//in case of integer overflow
if (result < 0) {
value.set(0);
return 0;
}
return result;
}
}
private static AtomicInteger count = new AtomicInteger(0);
count.set(0);
uniqueID = count.incrementAndGet();
Related
This question already has answers here:
Issue with Java 8 Lambda for effective final while incrementing counts
(3 answers)
Closed 4 years ago.
I am trying to count the number of iterations using Java lambda expressions, but it's throwing a compile time error:
Local variable count defined in an enclosing scope must be final or effectively final
public static void main(String[] args) {
List<String> names = new ArrayList<String>();
names.add("Ajeet");
names.add("Negan");
names.add("Aditya");
names.add("Steve");
int count = 0;
names.stream().forEach(s->
{
if(s.length()>6)
count++;
});
}
The statement count++; is reassigning the variable count.
This is not allowed in a lambda expression. A local variable referenced in a lambda must be final (or effectively final, which means that it is not explicitly declared final, but would not break if final were added)
The alternative is to use an atomic integer:
AtomicInteger count = new AtomicInteger();
names.stream().forEach(s -> {
if (s.length() > 6)
count.incrementAndGet();
});
Note that using an atomic integer should be used only if you need to modify the local variable. If all this is just for computing the count variable, then the approach in EliotFrish's answer is much better.
You can't access a non-final variable from an outer scope in a lambda. But you don't need to here, you can filter the stream based on your criteria and count that. Like,
long count = names.stream().filter(s -> s.length() > 6).count();
This answer is just here to provide a wider spectrum to overcome this error.
You can define your own consumer which counts:
class CountingConsumer implements Consumer<String>{
int count;
public void accept(String s){
if(s.length() > 6){
count++;
}
}
}
And then pass an instance of this new class to the consumer:
CountingConsumer countingConsumer = new CountingConsumer();
names.forEach(countingConsumer);
Which finally lets you extract the count after the iteration:
System.out.println(countingConsumer.count);
But an even better answer is just to use a normal for loop:
int count = 0;
for(String s : names){
if(s.length() > 6){
count++;
}
}
This is a class I've written and it feels 'clunky', like there should be a better way to set this up without needing the extra method setList() to instantiate the array. I'm trying to only leave in the parts relevant to my question, as well as an example of what I did the first time that threw a runtime (not compiletime) error. I'm still mostly used to interpreted languages, so the stricter rules of Java are taking some getting used to.
public class Numbersplode
{
// fields
private int before;
private int goal;
private int[] processed;
// constructors
Numbersplode(int begin, int finish)
{
this.before = begin;
this.goal = finish;
this.processed = this.setList(begin);
this.transList();
}
// mutators
private int[] setList(int begin)
{
int[] result = new int[begin];
return result;
}
public void transList()
{
// transforms the list
int count;
double temp;
for (count = 0; count < this.before; count++)
{
temp = (double)count/(double)this.before * (double)this.goal;
this.processed[count] = (int)temp;
}
}
}
It seems like I should be able to avoid having the setList() method, but when I tried this (everything else the same):
public class Numbersplode
{
// fields
private int before;
private int goal;
private int[] processed = new int[before];
// constructors
Numbersplode(int begin, int finish)
{
this.before = begin;
this.goal = finish;
this.transList();
}
[..............]
I receive java.lang.ArrayIndexOutOfBoundsException: 0 since processed[] apparently can't be defined that way.
That extra class seems to solve the problem, but it seems to me that the Constructor should define those variables all at the same time of object creation, thus allowing for the array processed to be defined at the same time in that way.
So is there a more elegant solution I'm missing? If I find one before this is solved I'll post it up here.
EDIT
Just to be clear, if I compile the class (or even a program that creates an object from that class) I don't have any problems until I actually run the program (thus the runtime problem vs compiletime, but wanted to be clear)
And why even have a setList() method -- a private(?) mutator. Why not simply set processed = new int[before] in your constructor?
Numbersplode(int before, int goal) {
this.before = before;
this.goal = goal;
processed = new int[before];
transList();
}
I am trying to understand this code from yammer metrics. The confusion starts with the trim method and the call to trim in both update and getSnapShot. Could someone explain the logic here say for a 15 min sliding window? Why would you want to clear the map before passing it into SnapShot (this is where the stats of the window are calculated).
package com.codahale.metrics;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class SlidingTimeWindowReservoir implements Reservoir {
// allow for this many duplicate ticks before overwriting measurements
private static final int COLLISION_BUFFER = 256;
// only trim on updating once every N
private static final int TRIM_THRESHOLD = 256;
private final Clock clock;
private final ConcurrentSkipListMap<Long, Long> measurements;
private final long window;
private final AtomicLong lastTick;
private final AtomicLong count;
public SlidingTimeWindowReservoir(long window, TimeUnit windowUnit) {
this(window, windowUnit, Clock.defaultClock());
}
public SlidingTimeWindowReservoir(long window, TimeUnit windowUnit, Clock clock) {
this.clock = clock;
this.measurements = new ConcurrentSkipListMap<Long, Long>();
this.window = windowUnit.toNanos(window) * COLLISION_BUFFER;
this.lastTick = new AtomicLong();
this.count = new AtomicLong();
}
#Override
public int size() {
trim();
return measurements.size();
}
#Override
public void update(long value) {
if (count.incrementAndGet() % TRIM_THRESHOLD == 0) {
trim();
}
measurements.put(getTick(), value);
}
#Override
public Snapshot getSnapshot() {
trim();
return new Snapshot(measurements.values());
}
private long getTick() {
for (; ; ) {
final long oldTick = lastTick.get();
final long tick = clock.getTick() * COLLISION_BUFFER;
// ensure the tick is strictly incrementing even if there are duplicate ticks
final long newTick = tick > oldTick ? tick : oldTick + 1;
if (lastTick.compareAndSet(oldTick, newTick)) {
return newTick;
}
}
}
private void trim() {
measurements.headMap(getTick() - window).clear();
}
}
Two bits of information from the documentation
ConcurrentSkipListMap is sorted according to the natural ordering of its keys
that's the datastructure to hold all measurements. Key here is a long which is basically the current time. -> measurements indexed by time are sorted by time.
.headMap(K toKey) returns a view of the portion of this map whose keys are strictly less than toKey.
The magic code in getTick makes sure that one time value is never used twice (simply takes oldTick + 1 if that would happen). COLLISION_BUFFER is a bit tricky to understand but it's basically ensuring that even through Clock#getTick() returns the same value you get new values that don't collide with the next tick from clock.
E.g.
Clock.getTick() returns 0 -> modified to 0 * 256 = 0
Clock.getTick() returns 1 -> modified to 1 * 256 = 256
-> 256 values room in between.
Now trim() does
measurements.headMap(getTick() - window).clear();
This calculates the "current time", subtracts the time window and uses that time to get the portion of the map that is older than "window ticks ago". Clearing that portion will also clear it in the original map. It's not clearing the whole map, just that part.
-> trim removes values that are too old.
Each time you update you need to remove old values or the map gets too large. When creating the Snapshot the same things happens so those old values are not included.
The endless for loop in getTick is another trick to use the atomic compare and set method to ensure that - once you are ready to update the value - nothing has changed the value in between. If that happens, the whole loop starts over & refreshes it's starting value. The basic schema is
for (; ; ) {
long expectedOldValue = atomic.get();
// other threads can change the value of atomic here..
long modified = modify(expectedOldValue);
// we can only set the new value if the old one is still the same
if (atomic.compareAndSet(expectedOldValue, modified)) {
return modified;
}
}
When return value is not of interest, is there any (even irrelevant in practice) difference between AtomicInteger.getAndIncrement() and AtomicInteger.incrementAndGet() methods, when return value is ignored?
I'm thinking of differences like which would be more idiomatic, as well as which would put less load in CPU caches getting synchronized, or anything else really, anything to help decide which one to use more rationally than tossing a coin.
Since no answer to the actual question has been given, here's my personal opinion based on the other answers (thanks, upvoted) and Java convention:
incrementAndGet()
is better, because method names should start with the verb describing the action, and intended action here is to increment only.
Starting with verb is the common Java convention, also described by official docs:
"Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized."
The code is essentially the same so it does not matter:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
No, there's no difference (if you don't care about the return value).
The code of those methods (in the OpenJDK) differs only in that one uses return next and the other uses return current.
Both use compareAndSet under the hood with the exact same algorithm. Both need to know both the old and the new value.
Just want to add to existing answers: there could be very small non-noticeable difference.
If you look at this implementation:
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
Note - both function call exactly the same function getAndAddInt, except +1 part, which means that in this implementation getAndIncrement is faster.
But, here is older implementation:
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
The only difference is return variable, so both functions perform exactly the same.
Here I am giving an example. Hope it will clear your doubt.
Suppose I have a variable i as
AtomicInteger i = new AtomicInteger();
In this case:
i.getAndIncrement() <==> i++;
And
i.incrementAndGet() <==> ++i;
Please have a look of the below programs
public class Test1
{
public static void main(String[] args)
{
AtomicInteger i = new AtomicInteger();
System.out.println(i.incrementAndGet());
System.out.println(i);
}
}
**output
1
1
======================================**
public class Test2
{
public static void main(String[] args)
{
AtomicInteger i = new AtomicInteger();
System.out.println(i.getAndIncrement());
System.out.println(i);
}
}
**output
0
1
-------------**
Comment:
1) In the class Test1, incrementAndGet() will first increment the i value and then print.
2) In the class Test2, getAndIncrement() will first print the i value and then increment.
That's all.
Doing a course on concurrent programming.
As an example we have
final class Counter {
private AtomicInteger value;
public long getValue() {
return value.get();
}
public long increment() {
int v;
do {
v = value.get();
}
while(!value.compareAndSet(v, v+1));
return v+1;
}
}
Why would you use compareAndSet in this case and not incrementAndGet ?
Thanks
Here the the implementation of AtomicInteger.incrementAndGet() method from the JDK version I have on my machine:
/**
* Atomically increments by one the current value.
*
* #return the updated value
*/
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
As you can see, the implementation is very similar to yours.
PS: Why do you compute v+1 twice?
From the Java docs,
compareAndSet :
Atomically sets the value to the given
updated value if the current value ==
the expected value.
public final boolean compareAndSet(V expect,
V update)
incrementAndGet :
Atomically increments by one the
current value.
public final int incrementAndGet()
Since compareAndSet basically does the same, I can't think about a single reason to use this handwritten implementation of increment.
In your case, the Class Counter implements the value increment in it's own way, and JDK AtomicInteger.incrementAndGet() also implements it in it's own way. But they also use the CAS method compareAndSet(V expect ,V newValue).
So these two kinds of implementation have no difference. The minor difference between the two ways is the circulation form. BTW, answer for compute v+1 twice.
while(!value.compareAndSet(v, v+1));----v+1 is the parameter for function , and realize value to add 1;
return v+1; v+1 is the return value;