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: 5,971 | Comments: 44,508

filter by tags archive

Detailed Answer: Your own ThreadLocal

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. Paying the rent online - 3 days from now

There are posts all the way to Aug 03, 2015


  1. Production postmortem (5):
    29 Jul 2015 - The evil licensing code
  2. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
  3. API Design (7):
    20 Jul 2015 - We’ll let the users sort it out
  4. What is new in RavenDB 3.5 (3):
    15 Jul 2015 - Exploring data in the dark
  5. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats