Java Concurrency: Synchronized Method and Block

In this blog post you’ll read about what is thread synchronization in java and when to use synchronization. Also, we’ll cover some basic examples of how to write synchronized methods and blocks in java.

What is Synchronization in Java?

In a concurrent application, when multiple threads are accessing a shared resource, we need to make sure threads wouldn’t access critical parts of the code at the same time. A critical part of the code might be for example reading from and writing to a file. If two threads would write to the file at the same time, we would very likely end up with unexpected results. This is where synchronization comes into help.

Synchronization in java is a way of restricting threads of getting access to shared resources at the same time. This means that only one thread is allowed to access a synchronized resource at a time. In case other threads also want to access the resource, they will have to wait until the resource gets freed.

To synchronize a resource, we can use a synchonized method or a synchronized block in java.

When to use Synchronization in Java?

We should use synchronization in java for objects that are shared among multiple threads. In case the object is read-only or immutable, we don’t need to synchronize access to it. Java thead synchronization makes sure that objects are modified by only one thread at a time and that threads are prevented from accessing partially updated objects.

How to Synchronize Threads in Java?

We have several options to synchronize threads in java. These include for example synchronized methods and synchronized blocks. Synchronized methods and blocks are both synchronized on some object that is also known as monitor.  In fact, in java, any object could be a monitor.

Only one thread can enter a synchronized method or block at a time. This means that other threads that are trying to enter the same synchronized method/block are going to be blocked until the resource will be released by the current thread.

Synchronized method example

Let’s create a simple java synchronized method example. To define a synchronized method in java, we need to use the synchronized keyword in the method declaration.

In the following example we create a simple Counter class (a monitor). We’ll also create two threads in the main method that will call our synchronized method increment. Only one thread at a time will be allowed to enter this method.

public class Counter {

    private int count;

    // Synchronized method. Only one thread can execute it at a time
    private synchronized void increment() {
        for (int i = 0; i < 10000; i++) {
            count++;
        }
    }

    private int getCount() {
        return count;
    }

    static class CounterTask extends Thread {

        private Counter counter;

        CounterTask(Counter counter) {
            this.counter = counter;
        }

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

    }

    public static void main(String[] args) throws InterruptedException {
        // Create monitor object
        Counter counter = new Counter();

        // Create threads
        CounterTask task1 = new CounterTask(counter);
        CounterTask task2 = new CounterTask(counter);

        // Start the threads
        task1.start();
        task2.start();

        // Wait for threads to end
        task1.join();
        task2.join();

        System.out.println("Count: " + counter.getCount());
    }
}

Output:

Count: 20000

If we wouldn’t have synchronized the increment method the output could have been a totally random number.

Synchronized block example

Sometimes there is no need to synchronize the whole method. For example when only a part of your method is critical enough to be protected from multiple threads accessing it.

Following is an example of a synchronized block based on the synchronized increment method represented in the previous example.

private void increment() {
    // Synchronized block. Only one thread can execute it at a time
    synchronized(this){
        for (int i = 0; i < 10000; i++) {
            count++;
        }
    }
}

Conclusion

Threads in java are lightweight processes. They share the same resources among each other. Therefore it is important to synchronize access to critical parts of our system that are shared between several threads. In case the shared resource is immutable or read-only there is no need to add synchronization. To achieve thread-safe sections of our code we can use synchronized methods and blocks in java.

Be the first to reply

Leave a Reply

Your email address will not be published. Required fields are marked *