Your code is, of course, the first step into the world of threading, and you just experienced the first (of many) headaches!
To begin with, static can allow you to exchange a variable between threads, but that does not make it a safe thread. This means that your expression count < max and count++ not guaranteed to be a relevant or effective protector between threads. Look at the output of your program when max only 10 (t is set to 4, on my 8-processor workstation):
T0 - 0 T0 - 1 T0 - 2 T0 - 3 T1 - 0 // wait T1 got count = 0 too! T2 - 1 // and T2 got count = 1 too! T2 - 6 T2 - 7 T2 - 8 T2 - 9 T0 - 4 T3 - 1 // and T3 got count = 1 too! T1 - 5
To your question about each print stream, one after another, I assume that you are trying to coordinate access to count . You can accomplish this with synchronization primitives (such as the lock statement in C #). Here is a naive modification of your code that will only provide max increments:
static object countLock = new object(); public static void printWithLock() {
This simple modification makes your program logically correct, but also slow. A new problem now appears in the sample: block conflict. Each thread now vies for access to countLock . We made our program safe, but without any benefits of parallelism!
Threading and parallelism are not very easy to get right, but, fortunately, the latest versions of .Net come with Task Parallel Library (TPL) and Parallel LINQ (PLINQ) .
The beauty of the library is how easy it would be to convert your current code:
var sw = new Stopwatch(); sw.Start(); Enumerable.Range(0, max) .AsParallel() .ForAll(number => Console.WriteLine("T{0}: {1}", Thread.CurrentThread.ManagedThreadId, number)); Console.WriteLine("{0} ms elapsed", sw.ElapsedMilliseconds); // Sample output from max = 10 // // T9: 3 // T9: 4 // T9: 5 // T9: 6 // T9: 7 // T9: 8 // T9: 9 // T8: 1 // T7: 2 // T1: 0 // 30 ms elapsed
The above result is an interesting illustration of why threads produce "unexpected results" for new users. When threads execute in parallel, they can fill in pieces of code at different points in time, or one thread may be faster than another. You never know with threads!