Friday, October 22, 2010

Are java constructors thread safe ?

For instance fields YES ...
For static fields NO...
Let's Proove it ...

public class TestObject {
    private static int dangerInt =0 ;

    public TestObject () {
            dangerInt++;
            System.out.println (" Current Value of i :" + dangerInt + "     # -- " + Thread.currentThread ().getName ());
    }
}

public class ConstructorTest {

    public static void main (String[] args) {
        final ConstructorTest test = new ConstructorTest();

        final Runnable r = new Runnable () {
            public void run () {
                while (true) {
                    try {
                        test.printSomething ();
                        Thread.sleep (500);
                    } catch (Exception ex) {
                        System.out.println (" -- Interrupted...");
                        ex.printStackTrace ();
                    }
                }
            }
        };

        for (int i = 0; i < 10; i++) {
            new Thread (r).start ();
        }

    }

    public void printSomething (){
        new TestObject ();
    }
}
Output :  Current Value of i :2     # -- Thread-1
 Current Value of i :2     # -- Thread-0
 Current Value of i :3     # -- Thread-2
 Current Value of i :4     # -- Thread-3
 Current Value of i :5     # -- Thread-4
 Current Value of i :6     # -- Thread-5
 Current Value of i :7     # -- Thread-6
 Current Value of i :8     # -- Thread-7
 Current Value of i :9     # -- Thread-8
 Current Value of i :10     # -- Thread-9
 Current Value of i :11     # -- Thread-1
 Current Value of i :12     # -- Thread-0
 Current Value of i :13     # -- Thread-2
 Current Value of i :14     # -- Thread-3
 Current Value of i :15     # -- Thread-4
 Current Value of i :16     # -- Thread-5
 Current Value of i :17     # -- Thread-6
 Current Value of i :18     # -- Thread-7
 Current Value of i :19     # -- Thread-8
 Current Value of i :20     # -- Thread-9
 Current Value of i :21     # -- Thread-1
 Current Value of i :22     # -- Thread-0
 Current Value of i :23     # -- Thread-2
 Current Value of i :24     # -- Thread-3
 Current Value of i :25     # -- Thread-4
 Current Value of i :26     # -- Thread-5
 Current Value of i :27     # -- Thread-6
 Current Value of i :28     # -- Thread-7
 Current Value of i :29     # -- Thread-8
 Current Value of i :30     # -- Thread-9
 Current Value of i :31     # -- Thread-1
 Current Value of i :32     # -- Thread-0
 Current Value of i :33     # -- Thread-2
 Current Value of i :34     # -- Thread-3
 Current Value of i :35     # -- Thread-4
 Current Value of i :36     # -- Thread-5
 Current Value of i :37     # -- Thread-6
 Current Value of i :38     # -- Thread-7
 Current Value of i :39     # -- Thread-8
 Current Value of i :40     # -- Thread-9
 Current Value of i :41     # -- Thread-1
 Current Value of i :42     # -- Thread-0
 Current Value of i :43     # -- Thread-2
 Current Value of i :44     # -- Thread-3
 Current Value of i :45     # -- Thread-4
 Current Value of i :46     # -- Thread-5
 Current Value of i :47     # -- Thread-6
 Current Value of i :48     # -- Thread-7
 Current Value of i :49     # -- Thread-8
 Current Value of i :50     # -- Thread-9
 Current Value of i :51     # -- Thread-1
 Current Value of i :53     # -- Thread-3
 Current Value of i :55     # -- Thread-5
 Current Value of i :57     # -- Thread-7
 Current Value of i :54     # -- Thread-6
 Current Value of i :58     # -- Thread-8
 Current Value of i :56     # -- Thread-4
 Current Value of i :52     # -- Thread-2
 Current Value of i :51     # -- Thread-0

3 comments:

  1. Actually this is not an issue about constructors, this is a general synchronization issue that is unrelated with constructors. Constructors are like any other method when it comes to synchronization.

    ReplyDelete
  2. public Class MyClass{

    private SomeType someInstanceField;
    private SomeOtherType someOtherInstanceField;

    public void MyClass (SomeType someValue, SomeOtherType someOtherValue){//synchronization here is unnecessary
    this.someInstanceField = someValue;
    this.someOtherInstanceField = someOtherValue;
    }

    public void synchronized setSomeInstanceVariables (SomeType someValue, SomeOtherType someOtherValue){//synchronization here is necessary
    this.someInstanceField = someValue;
    this.someInstanceField = someOtherValue;
    }

    }

    So there is small difference between constructors and any other methods bro.Think twice :)

    ReplyDelete
  3. Initialization of fields is guarenteed under JSR-133, but not mutation of static fields. IMHO You shouldn't set static fields in a constructor. ;)

    ReplyDelete