简体   繁体   中英

Not getting desired result when using synchronized keyword in Java multithreading

I have two files, App.java and Runner.java

App.java -->

public class App {
    private static Thread thread1 = new Runner(1);
    private static Thread thread2 = new Runner(2);

    public static void main(String[] args) throws InterruptedException {
        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        System.out.printf("Count = %d\n", Runner.getCount());
    }
}

Runner.java -->

public class Runner extends Thread {
    private volatile static int count = 0;
    private int option = 0;

    private synchronized void increment() {
        count++;
    }

    private synchronized void decrement() {
        count--;
    }

    public Runner(int option) {
        this.option = option;
    }

    public static int getCount() {
        return count;
    }

    @Override
    public void run() {
        switch (option) {
            case 1:
                for (int i = 1; i <= 10000; i++) {
                    increment();
                }
                break;
            case 2:
                for (int i = 1; i <= 10000; i++) {
                    decrement();
                }
                break;
        }
    }
}

Here I am trying to create two threads from main thread and access a common variable from both the threads where both the threads will manipulate this common variable at the same time.

I am trying to create a demo for implementation for the synchronized keyword.

In my example, in Runner.java -

I am making Runner class a child class of Thread using extends keyword and overriding the run() method in body.

Next, I am using a constructor to get an option and running the respective code in run() method in a switch - case block . The common variable is count which is static with initial value 0.

There are two methods , both use the synchronized keyword - increment() and decrement() which increase and decrease the value of count by 1 respectively.

For option 1 run() method uses a for loop to run increment() 10,000 times. For option 2 run() method uses a for loop to run decrement() 10,000 times.

As such the end value of count should be 0.

In App.java -

I am creating two threads - thread1 , thread2 which are instances of Runner class and passing constructor argument 1 and 2 respectively.

I am running the two threads using thread.start() and waiting for completion of the two threads using thread.join()

Now, I am printing the value of count . The value is expected to be 0. But it is not. In each execution it is near to 0 but not 0.

So, where am I going wrong and how to correct my code?

count is static meaning there is only one such variable. Both increment and decrement are not static which means they are synchronized on this - that is two separate Runner instances.

Make those method static:

private synchronized static void increment() {
    count++;
}

private synchronized static void decrement() {
    count--;
}

or use explicit mutex object:

private static int count = 0;
private static Object mutex = new Object;

private int option = 0;

private void increment() {
    synchronized (mutex) {
        count++;
    }
}

private void decrement() {
    synchronized (mutex) {
        count--;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM