关闭

线程同步及线程用到的锁对象

437人阅读 评论(0) 收藏 举报

转自:http://blog.csdn.net/ghostbear/article/details/7328686

 

如果程序涉及到多个线程协同完成某项任务,那么你将会面对线程同步的问题。.Net为这类为题提供了很好的解决方案,我们只需要书写少量的代码就能避免线程出现死锁。

线程同步

辅助类  

  1. class ThreadSync 
  2.  
  3.     { 
  4.  
  5.         public long data1; 
  6.  
  7.         public long data2; 
  8.  
  9.   
  10.  
  11.         public void Increase() 
  12.  
  13.         { 
  14.  
  15.             data2++; 
  16.  
  17.         } 
  18.  
  19.  
  20.   
  21.  
  22.     class AlgorithmicTimer 
  23.  
  24.     { 
  25.  
  26.         public DateTime startTime { get; set; } 
  27.  
  28.         public DateTime endTime { get; set; } 
  29.  
  30.   
  31.  
  32.         public void Analyse() 
  33.  
  34.         { 
  35.  
  36.             Console.WriteLine( 
  37.  
  38. string.Format("当前程序共运行了:{0}秒" 
  39.  
  40. , (endTime - startTime).TotalSeconds)); 
  41.  
  42.         } 
  43.  
  44.   
  45.  
  46.   
  47.  
  48.     } 
  49.  


调用代码

  1. ThreadSync myThreadSync = new ThreadSync(); 
  2.  
  3. AlgorithmicTimer timer = new AlgorithmicTimer(); 
  4.  
  5.              
  6.  
  7.     timer.startTime = DateTime.Now; 
  8.  
  9.     for (int i = 0; i < 100000000; i++) 
  10.  
  11.     { 
  12.  
  13.         myThreadSync.Increase(); 
  14.  
  15.  
  16.   
  17.  
  18.     Console.WriteLine(myThreadSync.data2); 
  19.  
  20.     timer.endTime = DateTime.Now; 
  21.  
  22.     timer.Analyse(); 
  23.  
  24.              
  25.  
  26.     myThreadSync.data2 = 0; 
  27.  
  28.     timer.startTime = DateTime.Now; 
  29.  
  30.     Parallel.For(0, 100000000, (index) => 
  31.  
  32.     { 
  33.  
  34.         lock (myThreadSync)  //不加上Lock得到的结果不正确 
  35.  
  36.         { 
  37.  
  38.             myThreadSync.Increase(); 
  39.  
  40.         } 
  41.  
  42. }); 
  43.  
  44.   
  45.  
  46.     Console.WriteLine(myThreadSync.data2); 
  47.  
  48.     timer.endTime = DateTime.Now; 
  49.  
  50.     timer.Analyse(); 


执行结果

 

100000000

当前程序共运行了:1.1740671秒

100000000

当前程序共运行了:11.4436546秒

PV信号量操作

  1. //Semaphore 信号量对象,PV 操作 
  2.  
  3. int threadCount = 6; 
  4.  
  5. int semaphoreCount = 4; 
  6.  
  7. var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount); 
  8.  
  9. var threads = new Thread[threadCount]; 
  10.  
  11.  
  12.  
  13. for (int i = 0; i < threadCount; i++) 
  14.  
  15.  
  16.      threads[i] = new Thread(mysemaphore.ThreadMain); 
  17.  
  18.      threads[i].Start(semaphore); 
  19.  
  20.  
  21.  
  22.  
  23. for (int i = 0; i < threadCount; i++) 
  24.  
  25.  
  26.      threads[i].Join(); 
  27.  
  28.  
  29. Console.WriteLine("All threads finished!"); 


Mysemaphore类型

  1. using System; 
  2.  
  3. using System.Collections.Generic; 
  4.  
  5. using System.Linq; 
  6.  
  7. using System.Text; 
  8.  
  9.   
  10.  
  11. using System.Threading; 
  12.  
  13. using System.Threading.Tasks; 
  14.  
  15. using System.Diagnostics; 
  16.  
  17.   
  18.  
  19. namespace chapter20 
  20.  
  21.  
  22.     class mysemaphore 
  23.  
  24.     { 
  25.  
  26.         public static  void ThreadMain(object o) 
  27.  
  28.         { 
  29.  
  30.             SemaphoreSlim semaphore = o as SemaphoreSlim; 
  31.  
  32.             Trace.Assert(semaphore != null, "o must be a Semaphore type"); 
  33.  
  34.             bool isCompleted = false
  35.  
  36.             while (!isCompleted) 
  37.  
  38.             { 
  39.  
  40.                 if (semaphore.Wait(600)) 
  41.  
  42.                 { 
  43.  
  44.                     try 
  45.  
  46.                     { 
  47.  
  48.                         Console.WriteLine("Thread {0} locks the semaphore 
  49.  
  50. ,Current PV:{1}" 
  51.  
  52. , new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount}); 
  53.  
  54.                         
  55.  
  56.                         Thread.Sleep(2000); 
  57.  
  58.                     } 
  59.  
  60.                     finally 
  61.  
  62.                     { 
  63.  
  64.                         semaphore.Release(); 
  65.  
  66.                         Console.WriteLine("Thread {0} release the semaphore,Current PV:{1}", new object[]{Thread.CurrentThread.ManagedThreadId,semaphore.CurrentCount}); 
  67.  
  68.                       
  69.  
  70.                         isCompleted = true
  71.  
  72.                     } 
  73.  
  74.                 } 
  75.  
  76.                 else 
  77.  
  78.                 { 
  79.  
  80.                     Console.WriteLine("Timeout for thread {0},wait again", Thread.CurrentThread.ManagedThreadId); 
  81.  
  82.                 } 
  83.  
  84.             } 
  85.  
  86.         } 
  87.  
  88.     } 
  89.  


执行结果:

 

Thread 9 locks the semaphore,Current PV:3

Thread 10 locks the semaphore,Current PV:2

Thread 11 locks the semaphore,Current PV:1

Thread 12 locks the semaphore,Current PV:0

Timeout for thread 13,wait again

Timeout for thread 14,wait again

Timeout for thread 13,wait again

Timeout for thread 14,wait again

Thread 9 release the semaphore,Current PV:1

Thread 13 locks the semaphore,Current PV:0

Thread 11 release the semaphore,Current PV:2

Timeout for thread 14,wait again

Thread 10 release the semaphore,Current PV:1

Thread 14 locks the semaphore,Current PV:2

Thread 12 release the semaphore,Current PV:3

Thread 13 release the semaphore,Current PV:3

Thread 14 release the semaphore,Current PV:4

All threads finished!

Event类

    解决资源分配问题,当程序释放资源时改变该事件的状态。通知其他程序它释放了资源。

辅助类

   

  1. class Calculator 
  2.  
  3.     { 
  4.  
  5.         private ManualResetEventSlim mEvent; 
  6.  
  7.         public int Result { get; private set; } 
  8.  
  9.         public Calculator(ManualResetEventSlim ev) 
  10.  
  11.         { 
  12.  
  13.             this.mEvent = ev; 
  14.  
  15.         } 
  16.  
  17.   
  18.  
  19.         public void Calculation(object obj) 
  20.  
  21.         { 
  22.  
  23.             Tuple<int, int> data = obj as Tuple<int, int>; 
  24.  
  25.             Console.WriteLine("Task {0} starts calculation" 
  26.  
  27. , Task.CurrentId); 
  28.  
  29.             Thread.Sleep(new Random().Next(3000)); 
  30.  
  31.             Result = data.Item1 + data.Item2; 
  32.  
  33.   
  34.  
  35.             Console.WriteLine("Task {0} is ready", Task.CurrentId); 
  36.  
  37.             mEvent.Set(); 
  38.  
  39.         } 
  40.  
  41.  
  42.   


调用代码:

  

  1. //Event 类 
  2.  
  3.    int taskCount = 4; 
  4.  
  5.    var mEvents = new ManualResetEventSlim[taskCount]; 
  6.  
  7.    var waitHandles = new WaitHandle[taskCount]; 
  8.  
  9.    var calcs = new Calculator[taskCount]; 
  10.  
  11.  
  12.  
  13.    TaskFactory taskFactory = new TaskFactory(); 
  14.  
  15.    for (int i = 0; i < taskCount; i++) 
  16.  
  17.    { 
  18.  
  19.        mEvents[i] = new ManualResetEventSlim(false); 
  20.  
  21.        waitHandles[i] = mEvents[i].WaitHandle; 
  22.  
  23.        calcs[i] = new Calculator(mEvents[i]); 
  24.  
  25.  
  26.  
  27.        taskFactory.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3)); 
  28.  
  29.  
  30.  
  31.    } 
  32.  
  33.  
  34.  
  35.    for (int i = 0; i < taskCount; i++) 
  36.  
  37.    { 
  38.  
  39.        int index = WaitHandle.WaitAny(waitHandles); 
  40.  
  41.        if (index == WaitHandle.WaitTimeout) 
  42.  
  43.        { 
  44.  
  45.            Console.WriteLine("Timeout!!"); 
  46.  
  47.        } 
  48.  
  49.        else 
  50.  
  51.        { 
  52.  
  53.            mEvents[index].Reset(); 
  54.  
  55.            Console.WriteLine("finished task for {0},result:{1}", index, calcs[index].Result); 
  56.  
  57.        } 
  58.  
  59.  
  60.  
  61.    } 


执行结果:

 

Task 1 starts calculation

Task 3 starts calculation

Task 2 starts calculation

Task 4 starts calculation

Task 2 is ready

Task 3 is ready

Task 4 is ready

finished task for 1,result:6

finished task for 2,result:8

finished task for 3,result:10

Task 1 is ready

finished task for 0,result:4

ReadWriterLockSlim(同步资源的读写)

    呵呵,额对这个东西的产生表示很无解。

 

  1. class MyReadWriterLockSlim 
  2.  
  3.   { 
  4.  
  5.       private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 }; 
  6.  
  7.       private static ReaderWriterLockSlim rwl = new 
  8.  
  9.             ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); 
  10.  
  11.  
  12.  
  13.      public static void ReaderMethod(object reader) 
  14.  
  15.       { 
  16.  
  17.           try 
  18.  
  19.           { 
  20.  
  21.               rwl.EnterReadLock(); 
  22.  
  23.  
  24.  
  25.               for (int i = 0; i < items.Count; i++) 
  26.  
  27.               { 
  28.  
  29.                   Console.WriteLine("reader {0}, loop: {1}, item: {2}"
  30.  
  31.                         reader, i, items[i]); 
  32.  
  33.                   Thread.Sleep(40); 
  34.  
  35.               } 
  36.  
  37.           } 
  38.  
  39.           finally 
  40.  
  41.           { 
  42.  
  43.               rwl.ExitReadLock(); 
  44.  
  45.           } 
  46.  
  47.       } 
  48.  
  49.  
  50.  
  51.      public static void WriterMethod(object writer) 
  52.  
  53.       { 
  54.  
  55.           try 
  56.  
  57.           { 
  58.  
  59.               while (!rwl.TryEnterWriteLock(50)) 
  60.  
  61.               { 
  62.  
  63.                   Console.WriteLine("Writer {0} waiting for the write lock"
  64.  
  65.                         writer); 
  66.  
  67.                   Console.WriteLine("current reader count: {0}"
  68.  
  69.                         rwl.CurrentReadCount); 
  70.  
  71.               } 
  72.  
  73.               Console.WriteLine("Writer {0} acquired the lock", writer); 
  74.  
  75.               for (int i = 0; i < items.Count; i++) 
  76.  
  77.               { 
  78.  
  79.                   items[i]++; 
  80.  
  81.                   Thread.Sleep(50); 
  82.  
  83.               } 
  84.  
  85.               Console.WriteLine("Writer {0} finished", writer); 
  86.  
  87.           } 
  88.  
  89.           finally 
  90.  
  91.           { 
  92.  
  93.               rwl.ExitWriteLock(); 
  94.  
  95.           } 
  96.  
  97.       } 
  98.  
  99.  
  100.  
  101.      public static void Go() 
  102.  
  103.       { 
  104.  
  105.           var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None); 
  106.  
  107.           var tasks = new Task[6]; 
  108.  
  109.           tasks[0] = taskFactory.StartNew(WriterMethod, 1); 
  110.  
  111.           tasks[1] = taskFactory.StartNew(ReaderMethod, 1); 
  112.  
  113.           tasks[2] = taskFactory.StartNew(ReaderMethod, 2); 
  114.  
  115.           tasks[3] = taskFactory.StartNew(WriterMethod, 2); 
  116.  
  117.           tasks[4] = taskFactory.StartNew(ReaderMethod, 3); 
  118.  
  119.           tasks[5] = taskFactory.StartNew(ReaderMethod, 4); 
  120.  
  121.  
  122.  
  123.           for (int i = 0; i < 6; i++) 
  124.  
  125.           { 
  126.  
  127.               tasks[i].Wait(); 
  128.  
  129.           } 
  130.  
  131.       } 
  132.  
  133.   } 


执行结果:

 

reader 1, loop: 0, item: 0

reader 1, loop: 1, item: 1

reader 3, loop: 0, item: 0

Writer 1 waiting for the write lock

current reader count: 3

reader 4, loop: 0, item: 0

Writer 2 waiting for the write lock

reader 1, loop: 2, item: 2

reader 3, loop: 1, item: 1

current reader count: 3

reader 4, loop: 1, item: 1

reader 3, loop: 2, item: 2

reader 1, loop: 3, item: 3

reader 4, loop: 2, item: 2

Writer 1 waiting for the write lock

reader 3, loop: 3, item: 3

current reader count: 3

Writer 2 waiting for the write lock

reader 1, loop: 4, item: 4

reader 3, loop: 4, item: 4

reader 4, loop: 3, item: 3

current reader count: 3

Writer 1 waiting for the write lock

current reader count: 3

reader 3, loop: 5, item: 5

reader 1, loop: 5, item: 5

reader 4, loop: 4, item: 4

reader 4, loop: 5, item: 5

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

current reader count: 1

reader 2, loop: 0, item: 0

current reader count: 1

reader 2, loop: 1, item: 1

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

reader 2, loop: 2, item: 2

current reader count: 1

current reader count: 1

reader 2, loop: 3, item: 3

Writer 1 waiting for the write lock

Writer 2 waiting for the write lock

reader 2, loop: 4, item: 4

current reader count: 1

current reader count: 1

reader 2, loop: 5, item: 5

Writer 2 waiting for the write lock

Writer 1 waiting for the write lock

current reader count: 0

current reader count: 0

Writer 1 acquired the lock

Writer 2 waiting for the write lock

current reader count: 0

Writer 2 waiting for the write lock

current reader count: 0

Writer 2 waiting for the write lock

current reader count: 0

Writer 1 finished

Writer 2 acquired the lock

Writer 2 finished

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:156193次
    • 积分:1851
    • 等级:
    • 排名:千里之外
    • 原创:24篇
    • 转载:65篇
    • 译文:0篇
    • 评论:26条