I have written a multi-threaded and synchronized incrementing function but it doesn’t show a consistent output :-
$ java Main
count: 999883
$ java Main
count: 1000000
$ java Main
count: 999826
$ java Main
count: 1000000
$ java Main
count: 1000000
I have a synchronized counter :-
public class Counter {
public int count;
synchronized void inc() {
count = count+1;
}
int getCount() {
return count;
}
}
A thread class that is initialized with a counter object and increments it 1000 times :-
public class CountPrimesRunnable implements Runnable {
private Counter c;
public CountPrimesRunnable(Counter c) {
this.c = c;
}
public void run() {
for (int i = 0; i < 1000; i++)
c.inc();
}
}
And the Main class that creates 1000 threads at a time :-
public class Main {
public static void main(String[] args) {
int numberOfThreads = 1000;
Thread[] worker = new Thread[numberOfThreads];
Counter c = new Counter();
for (int i = 0; i < numberOfThreads; i++)
worker[i] = new Thread(new CountPrimesRunnable(c));
for (int i = 0; i < numberOfThreads; i++)
worker[i].start();
System.out.println("count: " + c.count);
}
}
What is it that I am missing ?
That’s because, it’s not sure from your code that
mainthread will always finish after all the other threads are done with their job. In some cases where you get result less than1000000, are the cases, where some threads still execute after the main thread has finished.You can invoke
Thread#join()method on each of the newly created thread to make sure that themainmethod waits for all those threads to die, before continuing execution after for loop.So, you will have to add another for loop to invoke
joinon each of the threads started, and also you can avoid using the 2nd for loop, by merging it with the first one:When you invoke
joinon aThread Afrom inside aThread B, theThread Bwill continue the further execution only afterThread Adies.