Unordered thread problem

I asked about the lock here , and people answered that there are no problems in my implementation of the lock. But I caught the problem. Here is the same implementation of locking, and I get a strange result. I expect numbers to start at 1, but start at 5. An example is below.

class Program
{
    static object locker = new object();
    static void Main(string[] args)
    {
        for (int j = 0; j < 100; j++)
        {
            (new Thread(new ParameterizedThreadStart(dostuff))).Start(j);
        }
        Console.ReadKey();
    }
    static void dostuff(dynamic input)
    {
        lock (locker)
        {
            Console.WriteLine(input);
        }
    }
}
+2
source share
3 answers

Code is OK. But you cannot guarantee the execution order of the threads. When I run the code, I get:

0 1 3 5 2 4 6 10 9 11 7 12 8 etc.

If you need to start threads in this order, you can use instead ThreadPool.QueueUserWorkItem.

class Program
{
      static object locker = new object();
      static EventWaitHandle clearCount 
          =new EventWaitHandle(false, EventResetMode.ManualReset);
  static void Main(string[] args)
  {
    for (int j = 0; j < 100; j++)
    {
       ThreadPool.QueueUserWorkItem(dostuff, j);
    }
    clearCount.WaitOne();
  }
  static void dostuff(dynamic input)
  {
    lock (locker)
    {
      Console.WriteLine(input);
          if (input == 99) clearCount.Set();
     }
   }
}
+3
source

, , , , . , , .

, , , - , - @Mikael Svenson.

, :

class Program
{
    static object locker = new object();
    static int count=0;

    static void Main(string[] args)
    {
        for (int j = 0; j < 100; j++)
        {
            (new Thread(new ParameterizedThreadStart(dostuff))).Start(j);
        }
        Console.ReadKey();
    }

    static void dostuff(object Id)
    {
        lock (locker)
        {
            count++;
            Console.WriteLine("Thread {0}: Count is {1}", Id, count);
        }
    }
}

, , , . , .

+1

.

  • 100 .
  • , .
  • , , , , , .

, , , . . ThreadPool, Parallel Task.

I included a sample sample using the method Parallel.For. To make the selection understandable, let's say you have a list of objects that you want to clone and fall into a separate list. Suppose the cloning operation is expensive and that you want to parallelize the cloning of many objects. Here's how you do it. Pay attention to the placement and limited use of the keyword lock.

public static void Main()
{
  List<ICloneable> original = GetCloneableObjects();
  List<ICloneable> copies = new List<ICloneable>();
  Parallel.For(0, 100,
    i =>
    {
      ICloneable cloneable = original[i];
      ICloneable copy = cloneable.Clone();
      lock (copies)
      {
        copies.Add(copy);
      }
    });
}
+1
source

All Articles