1. 程式人生 > >C#多執行緒同步的幾種方法

C#多執行緒同步的幾種方法


9.ReaderWriterLockSlim 

讀寫鎖的概念很簡單,允許多個執行緒同時獲取讀鎖,但同一時間只允許一個執行緒獲得寫鎖,因此也稱作共享-獨佔鎖。在C#中,推薦使用ReaderWriterLockSlim類來完成讀寫鎖的功能。某些場合下,對一個物件的讀取次數遠遠大於修改次數,如果只是簡單的用lock方式加鎖,則會影響讀取的效率。而如果採用讀寫鎖,則多個執行緒可以同時讀取該物件,只有等到物件被寫入鎖佔用的時候,才會阻塞。簡單的說,當某個執行緒進入讀取模式時,此時其他執行緒依然能進入讀取模式,假設此時一個執行緒要進入寫入模式,那麼他不得不被阻塞。直到讀取模式退出為止。同樣的,如果某個執行緒進入了寫入模式,那麼其他執行緒無論是要寫入還是讀取,都是會被阻塞的。

進入寫入/讀取模式有2種方法:

EnterReadLock嘗試進入寫入模式鎖定狀態。

TryEnterReadLock(Int32) 嘗試進入讀取模式鎖定狀態,可以選擇整數超時時間。

EnterWriteLock 嘗試進入寫入模式鎖定狀態。

TryEnterWriteLock(Int32) 嘗試進入寫入模式鎖定狀態,可以選擇超時時間。

退出寫入/讀取模式有2種方法:

ExitReadLock 減少讀取模式的遞迴計數,並在生成的計數為 0(零)時退出讀取模式。

ExitWriteLock 減少寫入模式的遞迴計數,並在生成的計數為 0(零)時退出寫入模式。

程式碼示例如下:

public class Program
	{
		static private ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();
		static void Main(string[] args)
		{
			Thread t_read1 = new Thread(new ThreadStart(ReadSomething));
			t_read1.Start();
			Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read1.GetHashCode());
			Thread t_read2 = new Thread(new ThreadStart(ReadSomething));
			t_read2.Start();
			Console.WriteLine("{0} Create Thread ID {1} , Start ReadSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_read2.GetHashCode());
			Thread t_write1 = new Thread(new ThreadStart(WriteSomething));
			t_write1.Start();
			Console.WriteLine("{0} Create Thread ID {1} , Start WriteSomething", DateTime.Now.ToString("hh:mm:ss fff"), t_write1.GetHashCode());
		}
		static public void ReadSomething()
		{
			Console.WriteLine("{0} Thread ID {1} Begin EnterReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
			rwl.EnterReadLock();
			try
			{
				Console.WriteLine("{0} Thread ID {1} reading sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
				Thread.Sleep(5000);//模擬讀取資訊
				Console.WriteLine("{0} Thread ID {1} reading end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
			}
			finally
			{
				rwl.ExitReadLock();
				Console.WriteLine("{0} Thread ID {1} ExitReadLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
			}
		}
		static public void WriteSomething()
		{
			Console.WriteLine("{0} Thread ID {1} Begin EnterWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
			rwl.EnterWriteLock();
			try
			{
				Console.WriteLine("{0} Thread ID {1} writing sth...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
				Thread.Sleep(10000);//模擬寫入資訊
				Console.WriteLine("{0} Thread ID {1} writing end.", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
			}
			finally
			{
				rwl.ExitWriteLock();
				Console.WriteLine("{0} Thread ID {1} ExitWriteLock...", DateTime.Now.ToString("hh:mm:ss fff"), Thread.CurrentThread.GetHashCode());
			}
		}
	}
以上為幾種執行緒同步方式,對於同步技術來說,還有很多種其他方式。能力有限,這裡只介紹這幾種。