1

I'm learning about synchronization and try to implement mutual exclusion, but even though I used join() method, main thread doesn't wait for two other to finish and counter ends with random number. The code:

public class Application {

    static volatile int counter = 10000000;

    public static void main(String[] args) throws InterruptedException {

        Runnable job = () -> {
            for (int i = 0; i < 5000000; i++) {
                counter--;
            }
        };

        long timeBefore = System.currentTimeMillis();
        Thread t1 = new Thread(job);
        Thread t2 = new Thread(job);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        long timeAfter = System.currentTimeMillis();
        long performance = timeAfter - timeBefore;
        System.out.println("Application finished with counter : " + counter);
        System.out.println("Application finished with time: " + performance + " ms");
    }
}

Is my understanding of join() is incorrect and it doesn't make calling thread to wait for referenced one with the method?

Erwol
  • 15
  • 4
  • 2
    Or maybe the threads both finished and the reason `counter` isn't what you expected is because you were altering it in two threads at the same time. `counter--` is not an atomic operation. – khelwood Dec 22 '21 at 22:11
  • as @khelwood mentioned "volatile" does not mean atomic. You can safely, concurrently read from a volatile but not increment/decrement. Those operations are essentially performing 3 steps (read, increment, write) which will not work consistently with multiple threads which is why you see varied results. One technique to use instead would be to change it to a "new AtomicInteger(10000000)" and use "counter.decrementAndGet()" instead. – jd314159 Dec 22 '21 at 22:46
  • Isn't it `volatile` keyword role to restrict access and update about changes until one thread finish its operation? – Erwol Dec 23 '21 at 20:20

0 Answers0