Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Singleton is not thread-safe

  1. #1
    Join Date
    Aug 2005
    Posts
    30

    Default Singleton is not thread-safe

    Hi,

    [Spring.NET 1.0.1]
    I use GetObject on IApplicationContext.GetObject to get a lazy-init singleton object from different threads. It seems that the method is not thread-safe. If I kick off two threads at the same time and get the object that takes time to initialize, one thread will get the object correctly while the other thread will get null back.

    I think this is a very important issue that has to be fixed since whether I configure the object to be singleton or not, it should not affect the code path directly.

    To workaround this problem, I need to put synchronize block around GetObject manually and I don't think it's a good idea. Is it possible to get it fixed in 1.0.2?


    http://opensource.atlassian.com/proj...wse/SPRNET-170

  2. #2
    Join Date
    Oct 2005
    Location
    Toulouse, France
    Posts
    1,409

    Default

    Hi,

    this issue seems to be close.

    Have you tried with one of the lastest nightly build ?
    http://www.springframework.net/downloads/nightly/
    My english is as poor as my taylor is rich

  3. #3
    Join Date
    Aug 2005
    Posts
    30

    Default

    It said that it is fixed in 1.0 but I'm using 1.0.1. So I think the bug is still there.

  4. #4
    Join Date
    Oct 2005
    Location
    Toulouse, France
    Posts
    1,409

    Default

    Hi,

    you right, the bug is still here, i reproduced it !

    Before to create a singleton object, Spring.NET puts a marker object into the cache :
    Code:
    /// <summary>
    /// Marker object to be temporarily registered in the singleton cache,
    /// while instantiating an object &#40;in order to be able to detect circular references&#41;.
    /// </summary>
    private static readonly object CURRENTLY_IN_CREATION = new Object&#40;&#41;;
    so if the instance creation takes time, the second thread, that calls the GetObject method, will find an object into the cache and will return it.
    the instance returned will be CURRENTLY_IN_CREATION = new Object().
    (You said it gets a null back, can you verify please ?)


    I fixed it, but need to talk with Mark or Aleks before.
    We'll try to add the fix for the 1.0.2.


    -Bruno
    My english is as poor as my taylor is rich

  5. #5
    Join Date
    Aug 2005
    Posts
    30

    Default

    I think you're right. I just use "as" keyword to cast it. So if it's not castable to the type I want. It will be null.

  6. #6
    Mark Pollack is offline Spring.NET Co-Lead Spring TeamSpring User
    Join Date
    Sep 2004
    Location
    New York, NY
    Posts
    1,683

    Default

    Hi,

    I've added back in some synchronization code that was accidentially removed after the initial fix. I've also added a test case for multithreaded lazy init singleton access that now pass with the current changes. These changes will be in the 1.0.2 release.

    Just a small note that I will be following up one loose-end on this topic with the Spring.Java guys as it seems the Java implementation can (rarely) throw a ObjectCurrentlyInCreationException exception that seems unecessary.

    Thanks for raising the issue.

    Cheers,
    Mark

  7. #7
    Join Date
    Aug 2005
    Posts
    30

    Default

    Mark,

    Thanks for addressing the issue. I kinda wondered why no one else raised this issue :wink:

    And yes... ObjectCurrentlyInCreationException seems to be useless. It should never throw that exception. Hopefully we don't have double locking problem that might cause such issue in IA-64 although not many people use it... haha :twisted:

  8. #8
    Join Date
    Aug 2005
    Posts
    30

    Default

    So did you get a word from Juergen why that exception can be thrown from the factory. I think in .NET, there should be no case we should throw that exception. The only plausible one is that when there are complex references among singletons, how can you get a singleton object with thread-safety

  9. #9
    Join Date
    Oct 2005
    Location
    Toulouse, France
    Posts
    1,409

    Default

    Hi,

    The ObjectCurrentlyInCreationException is raised when circular references are detected

    Code:
    <object id="testObject1" type="SpringTests.TestObject1, SpringTests">
            <constructor-arg name="arg" ref="testObject2" />
    </object>
    
    <object id="testObject2" type="SpringTests.TestObject2, SpringTests">
           <constructor-arg name="arg" ref="testObject1" />
    </object>
    -> throw ObjectCurrentlyInCreationException


    Regards,
    Bruno
    My english is as poor as my taylor is rich

  10. #10
    Join Date
    Aug 2005
    Posts
    30

    Default

    Thanks. That makes sense then. But if I remember correctly, I've seen someone has a use case there circular reference is needed. In that case, should I make A refers to B through DI while make B refers to A by using ContextRegistry.GetContext().GetObject("A")?

Similar Threads

  1. singleton attribute ignored?
    By srdjan in forum Core Container
    Replies: 5
    Last Post: 07-12-2007, 02:45 PM
  2. Dispose a singleton instance
    By oz_ko in forum Core Container
    Replies: 5
    Last Post: 10-21-2005, 05:13 AM
  3. Replies: 13
    Last Post: 08-01-2005, 07:04 AM
  4. Singleton or not singleton
    By samokk in forum Core Container
    Replies: 8
    Last Post: 07-10-2005, 07:25 PM
  5. Legacy Singleton
    By Ted Husted in forum Core Container
    Replies: 7
    Last Post: 05-13-2005, 05:26 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •