Reputation: 1043
Hi I was trying volatile. I create 10 threads from my main Thread and I print value of static counter from each thread.
The output is uncertain. Can anyone please let me know why its not working.
public class Main {
static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) {
while(counter.getAndIncrement() < 10){
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(counter.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
In this I also tried changing the counter as
static volatile int counter = 0;
The out put I get is
3 3 6 6 7 7 10 10 11 11
The output is different every-time. I don't expect them in proper order but I expect unique values from 0 - 10.
Upvotes: 0
Views: 1925
Reputation: 533462
When you call
counter.getAndIncrement();
and much later in another thread call
System.out.println(counter.get());
then the values has nothing to do with one another.
If you want to retain a value, you need to do this in a variable which is not changing.
for (int i = 0; i < 10; i++) {
final threadId = i;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(threadId);
}
}).start();
}
The use of a volatile variable isn't needed but if you really want it you can do
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(counter.getAndIncrement());
}
}).start();
}
Upvotes: 4
Reputation: 73528
You have a single thread that's incrementing the value, and multiple threads that get and display the value. Obviously there's a lot of potential where the incrementing thread does it's thing, then the rest of the threads print the same value. Just because you call start()
doesn't mean that the thread would get to run before the value has been incremented.
If instead you put just get()
in the while loop, and use incrementAndGet()
in the other threads, you'll get unique values (although you'll probably get more than 10).
If you want to print exactly 10 distinct values, the code is not going to work.
With the original code, you create 10 threads, but when they run, they'll print the current value of counter. If 3 of the started threads run, they'll always print the same value.
When you move the get()
into the while loop, it can and will create more than 10 threads, since the other threads that increment counter won't have a chance to run yet, resulting in threads being created until 10 of the incrementing threads have run. After that there are still threads left that were created, but haven't run yet -> you get 10 + extra threads.
You can't get the output that you want with a single counter variable, if you want to use threads.
Upvotes: 6