AnswerBun.com

Why is synchronizing a method not advisable?

Stack Overflow Asked by linus jame on November 2, 2020

Consider the below code snippet:

public class DbSingleton {

    private static volatile DbSingleton instance = null;

    private DbSingleton() {
        if (instance != null) {
            throw new RuntimeException("Use getInstance()");
        }
    }

    public static DbSingleton getInstance() {
        if (instance == null) {
            synchronized (DbSingleton.class) {
                if (instance == null) {
                    instance = new DbSingleton();
                }
            }
        }
        return instance;
    }
}

Why is the above preferred to declaring getInstance() as synchronized? What does it mean when a method is declared as synchronized? Will it synchronize the entire class and slow down the performance?

3 Answers

Double-checked locking is evil and unnecessary, as is the Singleton antipattern. Also, initializing the static variable to null is a bad idea. Just initialize the variable as a final variable, or use an enum.

private static final DbSingleton instance = new DbSingleton();
…
public static DbSingleton getInstance() {
    return instance;
}

The instance is already lazily initialized when the class is, so any additional effort to accomplish that is stupid.

Answered by Lew Bloch on November 2, 2020

Acquiring a lock is expensive. In the given code, a lock is only acquired if instance == null.

Consider the following

  1. Thread A calls getInstance()
  2. Thread B calls getInstance()
  3. Thread A acquires the lock
  4. Thread B waits on the lock
  5. Thread A checks that instance == null initializes it, and releases the lock
  6. Thread B acquires the lock
  7. Thread B checks that instance != null and returns instance.

This scenario will happen with either a synchronized method or double checked locking. However, after the instance has been instantiated, consider the difference.

(This is the same as public static synchronized DbSingleton getInstance())

public static DbSingleton getInstance() {
    synchronized (DbSingleton.class) {
        if (instance == null) {
            instance = new DbSingleton();
        }
        return instance;
    }
}

With this method, after instance has been initialized..

  1. Thread A calls getInstance, acquires the lock, returns instance, and releases the lock
  2. Thread B calls getInstance, acquires the lock, returns instance, and releases the lock
  3. etc.

However, acquiring the lock is redundant in this case, which is the purpose of this code:

public static DbSingleton getInstance() {
    if (instance == null) {
        synchronized (DbSingleton.class) {
            if (instance == null) {
                instance = new DbSingleton();
            }
        }
    }
    return instance;
}

If instance does not equal null, a lock is never acquired and the flow looks like

  1. Thread A calls getInstance and returns instance (no lock)
  2. Thread B calls getInstance and returns instance (no lock)

Answered by Rubydesic on November 2, 2020

If you declare getInstance as synchronized, you will pay for the synchronization penalty every time you call getInstance even after it is initialized. With this implementation, getInstance will never go into a synchronized block after its first call because the instance is initialized already.

Answered by Burak Serdar on November 2, 2020

Add your own answers!

Related Questions

DASK can’t recognize workers on EMR

0  Asked on December 25, 2021 by cphoenix

         

Use external help file for C# programmed powershell cmdlet

0  Asked on December 25, 2021 by rivers-shall

     

Generate lexicographic permutations

2  Asked on December 23, 2021 by vishnu-prakash

     

How can i add a black layer over top of image with opacity?

3  Asked on December 23, 2021 by user13851719

   

How to add function to onChange in Input cmponent?

2  Asked on December 23, 2021 by will-black

       

Global variable to available

3  Asked on December 23, 2021 by havard-kleven

     

Integrating HTML pages to laravel

3  Asked on December 23, 2021 by user11195802

       

Run a counter in the background

1  Asked on December 23, 2021 by legacy-coding

   

Read from .csv, calculate, write on .csv

2  Asked on December 23, 2021 by irham-dollah

         

How to synchronize data between threads

2  Asked on December 23, 2021 by summit

     

Output is not as expected

3  Asked on December 23, 2021 by a4n

   

AWS Lambda query to Redshift once a day

2  Asked on December 23, 2021 by xbeta

         

Ask a Question

Get help from others!

© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP