Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 08 | Comments: 19

filter by tags archive

Detailed Answer: Your own ThreadLocal

time to read 4 min | 691 words

Originally posted at 12/15/2010

In the last post, we have shown this code:

public class CloseableThreadLocal
    public static Dictionary<object, object> slots;

    private readonly object holder = new object();
    private Dictionary<object, object> capturedSlots;

    private Dictionary<object, object> Slots
            if (slots == null)
                slots = new Dictionary<object, object>();
            capturedSlots = slots;
            return slots;

    public /*protected internal*/ virtual Object InitialValue()
        return null;

    public virtual Object Get()
        object val;

        lock (Slots)
            if (Slots.TryGetValue(holder, out val))
                return val;
        val = InitialValue();
        return val;

    public virtual void Set(object val)
        lock (Slots)
            Slots[holder] = val;

    public virtual void Close()
        if (capturedSlots != null)

        if (capturedSlots == null)
        lock (capturedSlots)

And then I asked whatever there are additional things that you may want to do here.

The obvious one is to thing about locking. For one thing, we have now introduced locking for everything. Would that be expensive?

The answer is that probably not. We can expect to have very little contention here, most of the operations are always going to be on the same thread, after all.

I would probably just change this to be a ConcurrentDictionary, though, and remove all explicit locking. And with that, we need to think whatever it would make sense to make this a static variable, rather than a thread static variable.



each instance is still only cleanning up the last thread's slots var that used it. The captured slots needs to be a list that will contain all the slots vars that that used the holder of a specific instance, and the d'tor needs to iterate over all those slots and clean them all up

  • you should cleanup:

  • after thread dies (threadstatic class with finalizer)

  • after closablethreadlocal goes out of scope

Also you'll probably need to sync this list both in Slots getter and in destructor(s)

Comment preview

Comments have been closed on this topic.


  1. Production postmortem: The case of the memory eater and high load - 3 days from now
  2. Production postmortem: The case of the lying configuration file - 4 days from now
  3. Production postmortem: The industry at large - 5 days from now
  4. The insidious cost of allocations - 6 days from now
  5. Find the bug: The concurrent memory buster - 7 days from now

And 4 more posts are pending...

There are posts all the way to Sep 10, 2015


  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    14 Aug 2015 - The case of the man in the middle
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats