Interlocked.increment still not solving value missing problems
I'm studying C# right now and currently learning threading.
Here is a simple example to adding 1 to a variable multiple tim开发者_如何学编程es within different threads.
The book suggested I can use Interlocked.increment(ref number)
to replace the number += 1
within the AddOne
method, therefore the value will be locked until it's updated within the thread. So the output will be 1000, 2000, ..... 10000
as expected. But My output is still 999, 1999, 2999, ...... 9999
.
Only after I uncomment the Thread.Sleep(1000)
line will the output be correct but even without the Interlocked
been used.
Can anyone explain what's happening here?
static void Main(string[] args)
{
myNum n = new myNum();
for (int i = 0;i<10; Interlocked.Increment(ref i))
{
for(int a =1;a<=1000; Interlocked.Increment(ref a))
{
Thread t = new Thread( new ThreadStart( n.AddOne));
t.Start();
}
//Thread.Sleep(1000);
Console.WriteLine(n.number);
}
}
class myNum
{
public int number = 0;
public void AddOne()
{
//number += 1;
Interlocked.Increment(ref number);
}
}
You are printing out the value before all of the threads have finished executing. You need to join all of the threads before printing.
for(int a = 0; a < 1000; a++)
{
t[a].Join();
}
You'll need to store the threads in an array or list. Also, you don't need the interlocked instruction in any of the for loops. They all run in only one thread (the main thread). Only the code in AddOne runs in multiple threads and hence needs to by synchronized.
It a bit strange for me what you trying to achieve with this code. You are using Interlocked.Increment
everywhere without explicit needs for it.
Interlocked.Increment
required for access to values which can be accessed from different threads. In your code it is only number
, so you don't require it for i
and a
, just use as usually i++
and a++
The problem you are asking for is that you just don't wait for all threads you started are completed its job. Take a look to Thread.Join() method. You have to wait while all of threads you are started completes its work.
In this simple test you are done with Thread.Sleep(1000);
you do similar wait but its not correct to assume that all threads are complete in 1000 ms, so just use Thread.Join()
for that.
If you modify your AddOne()
method so it starts to executes longer (e.g. add Thread.Sleep(1000)
to it) you'll notice that Thread.Sleep(1000);
doesn't help any more.
I'll suggest to read more about ThreadPool vs Threads. Also take a look to Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4
精彩评论