Thread[] threads = Enumerable.Range(0, 3).Select(remainder => new Thread(() =>
while (!finished && i % 3 != remainder) Monitor.Wait(locker);
Console.WriteLine($"Worker #{remainder} produced {i}");
Monitor.PulseAll(locker);
finally { finished = true; Monitor.PulseAll(locker); }
Array.ForEach(threads, t => t.Start());
Array.ForEach(threads, t => t.Join());