Search code examples
javajava.util.concurrent

Synchronized method multy threading app


I trying to use Synchronized methods, but I faced some interesting behavior such as:

I have three threads ThreadA - that invokes Increment method, ThreadB that invokes Decrement method and ThreadC that print current value; But some values look incorrect:

debug: Preparing threads false 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0....

when it's supposed to have all 0 and 1 or other values;

My code is below:

package concurrency;

public class Synchronization {

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

    System.out.println("Preparing threads");

    Counter cnt = new Counter();

    Thread threadA = new Thread(new ThreadA(cnt));

    Thread threadB = new Thread(new ThreadB(cnt));

    Thread ThreadC = new Thread (new ThreadC(cnt));


    threadA.start();
    threadB.start();
    ThreadC.start();
}

private static class ThreadA implements Runnable {

    private final Counter counter;

    public ThreadA(Counter cnt) {

        counter = cnt;

    }

    @Override
    public void run() {
        Thread.currentThread().setName("ThreadA");
        System.out.println(((Boolean) 
        Thread.currentThread().isInterrupted()).toString());
        try {
            while (!Thread.currentThread().isInterrupted()) {
                counter.Increment();
                Thread.sleep(1000);

            }
        } catch (InterruptedException ex) {
            System.out.println("InterruptedException ThreadA");
        }
        System.out.println("ThreadA finished");

    }
}

private static class ThreadB implements Runnable {

    private final Counter counter;

    public ThreadB(Counter cnt) {

        counter = cnt;
    }

    @Override
    public void run() {
        Thread.currentThread().setName("ThreadB");

        try {
            while (true) {

                if (Thread.currentThread().isInterrupted()) {

                    break;
                }
                counter.Decrement();

                Thread.sleep(1000);

            }
        } catch (InterruptedException ex) {
            System.out.println("InterruptedExcepion threadB");

        }
        System.out.println("ThreadB Finished");

    }
}

private static class ThreadC implements Runnable {

    private final Counter counter;

    public ThreadC(Counter cnt) {

        counter = cnt;
    }

    @Override
    public void run() {
        Thread.currentThread().setName("ThreadC");

        try {
            while (true) {

                if (Thread.currentThread().isInterrupted()) {

                    break;
                }
                System.out.println(counter.getValue());

                Thread.sleep(1000);

            }
        } catch (InterruptedException ex) {
            System.out.println("InterruptedExcepion threadB");

        }
        System.out.println("ThreadB Finished");

    }
}

private static class Counter {

    private int value = 0;

    public synchronized void Increment() {
        value++;
    }

    public synchronized void Decrement() {
        value--;
    }

    public synchronized int getValue() {
        return value;
    }

}
}

Solution

  • I don't know what you see here that is unexpected. This code has 3 threads using a common shared counter. There is sufficient synchronization to make sure threads don't modify the shared data in an invalid way or see stale values. But the output will vary depending on which threads get more CPU time when. There is no requirement that these threads run in any particular order, what threads run and who gets the lock may seem arbitrary. The output from this is going to be unpredictable.