0

I am learning threading with Java

I have the current code which fully works

What I find confusing is the counter value, I understand both threads are unsynchronized when accessing the Counter class, but since both threads fully run and the main thread waits for the sub threads to finish:

then shouldn't the value of the counter be 0 since the for loop for both threads was fully completed

Please note i am not asking for a solution to make the counter equal 0 as I know this already, I am just trying to understand the logic.

package com.company;

public class Unsynchronized extends Thread {

    private String name;
    private Counter mcounter;

    public Unsynchronized(String name, Counter counter) {
        this.name = name;
        this.mcounter = counter;
    }
    public void run() {
        for (int i = 0; i < 1000; i++) {
            mcounter.increment();
            mcounter.decrement();
        }
        System.out.println("Thread " +name+ " finished");
    }
    public static void main(String args[]) {

        String[] name = {"A", "B"};
        System.out.println("Master got started");

        Counter mcounter = new Counter();

        Thread[] slave = new Thread[name.length];

        for (int i = 0; i < name.length; i++) {
            slave[i] = new Unsynchronized(name[i], mcounter);
            slave[i].start();
        }
        System.out.println("Master will now wait for each Thread to finish");

        try{
            for (Thread s : slave)
                s.join();
        } catch (InterruptedException e) {
            System.out.println("Interruption before completion of the joins + e");
            System.out.println("Master has given up waiting for slaves");
        }

        System.out.println("counter should be 0 and actually is "
                + mcounter.get());
        System.out.println("Master is exiting");

    }
}
package com.company;

public class Counter {
    private int c = 0;

    public void increment() {
        c = c + 1;
    }

    public void decrement() {
        c = c - 1;
    }

    public int get() {
        return c;
    }
}
coderoftheday
  • 1,987
  • 4
  • 7
  • 21
  • 1
    Because ```c = c + 1``` and ```c = c - 1``` are non-atomic operations. https://stackoverflow.com/questions/25168062/why-is-i-not-atomic – zysaaa Apr 05 '22 at 14:58
  • @zysaaa, Thank you for finding a good "duplicate!" – Solomon Slow Apr 05 '22 at 15:06
  • @coderoftheday, 1000 is not a very big number. Try with ten million iterations. Also, I don't know how smart compilers and JIT can be these days. Try separating `increment()` calls and `decrement()` calls into different loops or even, into different threads. – Solomon Slow Apr 05 '22 at 15:10
  • Your code contains a race condition because the 'c=c+1' isn't atomic. But it also contains a race condition because c isn't volatile (or the methods not synchronized). – pveentjer Apr 06 '22 at 08:50

0 Answers0