1. resource competition
When multiple threads execute simultaneously while the need for global variables read-write operations, resource competition prone to problems, resulting in many cases run the results appear. Will be described in the following example:
private static CancellationTokenSource cs = new CancellationTokenSource(); private static int num = 5; private static object obj = new object(); static void Main(string[] args) { Console.WriteLine("Main Start...."); Task t1 = Task.Factory.StartNew(Test); Task t2 = Task.Factory.StartNew(Test); Task.WaitAll(new Task[] { t1, t2 }); cs.Dispose(); Console.WriteLine("Main end...."); Console.ReadLine(); } static void Test() { the while (! cs.IsCancellationRequested) // whether to invoke the Cancel { Console.WriteLine("TaskId {0} Excute other code....num is {1}",Task.CurrentId,num); if(num == 5){ The Thread.Sleep ( 50 ); // for easy viewing add delay NUM ++ ; Console.WriteLine("TaskId {0} and Num is {1}", Task.CurrentId, num); if (!cs.IsCancellationRequested) { cs.Cancel (); // cancel } } } }
In most cases, results are as follows:
Main Start....
TaskId 1 Excute other code....num is 5
TaskId 2 Excute other code....num is 5
TaskId 2 and Num is 6
TaskId 1 and Num is 7
Main end....
Task 1 First run to Thread.Sleep ( 50), wait 50ms, cpu start to run scheduled tasks 2 Thread.Sleep ( 50) . Then run the task 1 num ++, and outputs the result to the console num = 6, then task 2 run num ++, and outputs to the console num = 7. But sometimes this results appear below:
Main Start....
TaskId 1 Excute other code....num is 5
TaskId 2 Excute other code....num is 5
TaskId 2 and Num is 7
TaskId 1 and Num is 7
Main end....
Task 1 First run to Thread.Sleep ( 50), wait 50ms, cpu start to run scheduled tasks 2 Thread.Sleep ( 50). Then run the task 1 num ++, cpu scheduled task 2 starts immediately to run num ++, and outputs to the console num = 7, and finally to a scheduled task console output num = 7.
Solution: Just add thread lock lock, it will only be the first operating results, as follows:
static void Test() { the while (! cs.IsCancellationRequested) // whether to invoke the Cancel { Console.WriteLine("TaskId {0} Excute other code....num is {1}",Task.CurrentId,num); if(num == 5){ The Thread.Sleep ( 50 ); // for easy viewing delay added Lock (obj) // only one thread can operate { a ++ ; Console.WriteLine("TaskId {0} and Num is {1}", Task.CurrentId, num); } if (!cs.IsCancellationRequested) { cs.Cancel (); // cancel } } } }
2. Thread Deadlock
There are at least two threads are suspended, waiting for the other to unlock the thread will wait indefinitely.
private static int num = 5; private static object obj1 = new object(); private static object obj2 = new object(); static void Main(string[] args) { Console.WriteLine("Main Start...."); Parallel.Invoke (LockTest1, LockTest2); Console.WriteLine("Main end...."); Console.ReadLine(); } static void LockTest1 () { lock(obj1){ lock(obj2){ Console.WriteLine("LockTest1 is running"); } } } static void LockTest2 () { lock (obj2) { lock (obj1) { Console.WriteLine("LockTest2 is running"); } } }
operation result:
Main Start....
LockTest1 is running
LockTest2 is running
Main end....
Seemingly normal, but this program in a very few cases, there will be a deadlock. For example CPU to run LockTest1 () in Lock (obj1) , they immediately run LockTest2 () in Lock (obj2), then LockTest1 () will wait obj2 unlocked, and LockTest2 () will wait obj1 unlocked, form a deadlock.
Solution: In designing the program, regardless of the order of a good lock, or lock timeout defined.