Following example might help to understand the issue you are having.
class Job implements Runnable {
private int number = 0;
public void run() {
for (int i = 0; i < 1000000; i++) {
synchronized (this) {
this.number++;
}
}
}
public int getNumber() {
return number;
}
}
public class
Test {
public static void main(
String[] args) throws Exception {
Job job = new Job();
Thread t1 = new Thread(job, "t1");
Thread t2 = new Thread(job, "t2");
Thread t3 = new Thread(job, "t3");
t1.start();// at this point we have main thread and t1
t2.start();// so far we have main thread, t1 and t2
t3.start();// now we have total 4 threads which are main, t1, t2 and t3
// join/append Thread t1 at the end of main thread
// this would leave us total 3 thread main, t2 and t3
//t1.join();
// join/append Thread t2 at the end of main thread
// and this would leave main thread and t3
//t2.join();
// join/append Thread t3 at the end of main thread
// this would leave only main thread
//t3.join();
// making sure to print the number after finished three threads t1, t2, t3
while (true) {
if ((t1.getState() == Thread.State.TERMINATED) && (t2.getState() == Thread.State.TERMINATED) && (t3.getState() == Thread.State.TERMINATED)) {
// If this.number incrementation is not synchronized in run method,
// it is not guaranteed to satisfy number == 3000000
System.out.println(job.getNumber());
break;
}
}
}
}