Home > OS >  Will synchronized block in constructor of singleton calls synchronise the threads in Java?
Will synchronized block in constructor of singleton calls synchronise the threads in Java?

Time:11-20

I was trying something crazy :p

Created a TestClass (following singleton design pattern) A main method which initialise the reflection for TestClass and starts two thread which creates TestClass new instance using reflections.

Below is the code

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class SingletonPattern {
    public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        final TestClass[] i1 = {null};
        final TestClass[] i2 = {null};

        final Constructor<TestClass> constructor = TestClass.class.getDeclaredConstructor();
        constructor.setAccessible(true);

        Thread t3 = new Thread() {
            @Override
            public void run() {
                try {
                    i1[0] = constructor.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        Thread t4 = new Thread() {
            @Override
            public void run() {
                try {
                    i2[0] = constructor.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        t3.start();
        t4.start();
        t3.join();
        t4.join();
        System.out.println((i1[0] == i2[0])   "  "   i2[0].equals(i1[0]));
    }


    static class TestClass implements Cloneable, Serializable{
        private static TestClass instance;
        private static final Object obj = new Object();

        private TestClass() {
            synchronized (TestClass.class) {
                for (int i = 0; i < 100000; i  ) ;
                if (instance != null) {
                    throw new RuntimeException("Operation not allowed. Use getInstance method.");
                }
            }
        }

        public static TestClass getInstance() {
            if (instance == null) {
                synchronized (TestClass.class) {
                    if (instance == null) {
                        for (int i = 0; i < 100000; i  ) ;
                        instance = new TestClass();
                    }
                }
            }
            return instance;
        }

        public static TestClass getClone() {
            try {
                return (TestClass) instance.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return instance;
        }

        private Object readResolve() {
            return getInstance();
        }
    }
}

Output which I am getting

false false

If the synchronized block in constructor are really getting synchronised then I should be seeing some exception. But that is not happening.

Can anyone explain why its happing like this? I am using Java version : corretto-1.8.0_282

CodePudding user response:

If the synchronized block in constructor are really getting synchronised then I should be seeing some exception. But that is not happening.

In your constructor method, instance != null will always return false because instace is never assigned.

You can add instance = this, in this case, only one thread can construct an instance through reflection, and the others will get a exception:

       private TestClass() {
            synchronized (TestClass.class) {
                for (int i = 0; i < 100000; i  ) ;
                if (instance != null) {
                    throw new RuntimeException("Operation not allowed. Use getInstance method.");
                }
                instance = this;
            }
        }
  • Related