1. C# / Говнокод #12650

    +125

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    class OneAtATimePlease
      {
        private static object lok = new object();
    
        static void Main()
        {
          Dictionary<int, string> d = new Dictionary<int, string>();
          Thread t = new Thread(new ParameterizedThreadStart(Fill));
          Thread t2 = new Thread(new ParameterizedThreadStart(Fill));
          t.Start(d);
          t2.Start(d);
          t.Join();
          t2.Join();
          foreach (var i in d)
          {
            Console.WriteLine(i.Key + " " + i.Value);
          }
        }
    
        public static void Fill(object lo)
        {
          Dictionary<int, string> d = (Dictionary<int, string>)lo;
    
          for (int i = 0; i < 10; i++)
          {
            Random r = new Random(i*4);
            int v = r.Next(0, 10);
            if (!d.ContainsKey(v))
            {
              lock (lok)
              {
                d.Add(v, "Hello from thread: " + Thread.CurrentThread.ManagedThreadId);
              }
            }
          }
        }
      }

    Запостил: taburetka, 25 Февраля 2013

    Комментарии (5) RSS

    • С рандомом какое-то кручу-верчу-запутать-хочу непонятное... Зачем его на каждой итерации пересоздавать?

      А по делу - строку 28 надо бы внести под лок, ибо классический race condition. Да и вместо статического лока можно бы лочиться об саму мапу.

      P.S. А вообще, в шарпике же всяко есть какой-то аналог жабьего ConcurrentHashMap с его putIfAbsent()?
      Ответить
    • А словарь кто синхронизировать будет? foreach и ContainsKey находятся вне lock'а.
      Ответить
      • foreach то, простите, нахуя синхронизировать?

        К этому моменту треды остановлены, и по жабьей терминологии (не знаю как у вас в модели памяти шарпика это называется, но по идее должно быть что-то близкое) "завершение run() в треде happens before возврата управления из join()", поэтому все изменения словаря, внесенные тредами, гарантированно видны форичу, и какой-либо дополнительной синхронизации не требуется.

        ContainsKey да, надо внести, иначе имеем классический race condition.
        Ответить

    Добавить комментарий