How to show that the double-checked-lock pattern with Dictionary's TryGetValue is not threadsafe

后端 未结 5 701
南旧
南旧 2020-12-08 23:18

Recently I\'ve seen some C# projects that use a double-checked-lock pattern on a Dictionary. Something like this:

private static readonly object         


        
5条回答
  •  佛祖请我去吃肉
    2020-12-08 23:32

    In this example, exception #1 is thrown almost instantly on my machine:

    var dict = new Dictionary() { { 1234, "OK" } };
    
    new Thread(() =>
    {
        for (; ; )
        {
            string s;
            if (!dict.TryGetValue(1234, out s))
            {
                throw new Exception();  // #1
            }
            else if (s != "OK")
            {
                throw new Exception();  // #2
            }
        }
    }).Start();
    
    Thread.Sleep(1000);
    Random r = new Random();
    for (; ; )
    {
        int k;
        do { k = r.Next(); } while (k == 1234);
        Debug.Assert(k != 1234);
        dict[k] = "FAIL";
    }
    

    However, the exact behaviour of code that is not designed to be thread-safe is unpredictable.
    You cannot rely on it. So the double-checking code is indeed broken.

    I'm not sure if I'd unit test this, though, as testing concurrent code (and getting it right) is much more complicated than writing the concurrent code in the first place.

提交回复
热议问题