Java synchronized Modifier/Block - Exclusive Control in a Multithreaded Environment

synchronized

When manipulating shared data in a multithreaded environment, you must be careful about processing conflicts. The synchronized modifier is used for exclusive control in a multithreaded environment.

When synchronized Is Not Used

The following task increments the instance variable count simultaneously from multiple threads.

package com.devkuma.basic.thread;

public class SynchronizedSample {
    private int count;
    private static int THREAD_MAX = 300000;

    private static class MyThread implements Runnable {
        private SynchronizedSample _count;

        public MyThread(SynchronizedSample count) {
            this._count = count;
        }

        @Override
        public void run() {
            _count.increment();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedSample ss = new SynchronizedSample();
        Thread[] ts = new Thread[THREAD_MAX];
        for (int i = 0; i < THREAD_MAX; i++) {
            ts[i] = new Thread(new MyThread(ss));
            ts[i].start();
        }
        for (int i = 0; i < THREAD_MAX; i++) {
            ts[i].join();
        }
        System.out.println(ss.count);   // Result: 299944 (the result differs each time)
    }

    public void increment() {
        this.count++;
    }
}

The code above does not work correctly. In the this.count++ operation, another thread may interrupt after the count value is read and before it is incremented and assigned again.
Therefore, although the final result should originally be 300,000, a value such as 299999 may be returned.

synchronized Method

To prevent this, add the synchronized modifier to the increment method.

public synchronized void increment() {
    this.count++;
}

By doing this, the increment method will not be called simultaneously from multiple threads. Later callers wait until the earlier processing finishes. As a result, you can get 300,000 every time.

synchronized Block

The code above can also be rewritten using a synchronized block as follows.

public void increment() {
    synchronized(this) {
        this.count++;
    }
}