向執行緒傳遞引數
程式碼中實現了三種不同的方法向執行緒中傳遞引數。
1 /*----------------------------------------------------------------------- 2 written by helio, 2019 3 ThreadSample3 4 -----------------------------------------------------------------------*/ 5 using System; 6 using System.Threading; 7 8 namespace ThreadSample 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 var sample = new ThreadSample(10); 15 16 var ThreadOne = new Thread(sample.CountNumbers); 17 ThreadOne.Name = "ThreadOne"; 18 ThreadOne.Start(); 19 ThreadOne.Join(); 20 Console.WriteLine("------------------------"); 21 22 var ThreadTwo = new Thread(Count); 23 ThreadTwo.Name = "ThreadTwo"; 24 ThreadTwo.Start(8); 25 ThreadTwo.Join(); 26 Console.WriteLine("------------------------"); 27 28 var ThreadThree = new Thread(() => CountNumbers(12)); 29 ThreadThree.Name = "ThreadThree"; 30 ThreadThree.Start(); 31 ThreadThree.Join(); 32 Console.WriteLine("------------------------"); 33 34 int i = 10; 35 var ThreadFour = new Thread(() => PrintNumber(i)); 36 i = 20; 37 var ThreadFive = new Thread(() => PrintNumber(i)); 38 ThreadFour.Start(); 39 ThreadFive.Start(); 40 41 Console.ReadKey(); 42 } 43 44 static void Count(object iterations) 45 { 46 CountNumbers((int)iterations); 47 } 48 49 static void CountNumbers(int iterations) 50 { 51 for (int i = 1; i <= iterations; i++) 52 { 53 Thread.Sleep(TimeSpan.FromMilliseconds(0.5)); 54 Console.WriteLine("{0} prins {1}", 55 Thread.CurrentThread.Name, i); 56 } 57 } 58 59 static void PrintNumber(int number) 60 { 61 Console.WriteLine(number); 62 } 63 64 class ThreadSample 65 { 66 private readonly int m_iterations; 67 68 public ThreadSample(int iterations) 69 { 70 m_iterations = iterations; 71 } 72 public void CountNumbers() 73 { 74 for (int i = 1; i <= m_iterations; i++) 75 { 76 Thread.Sleep(TimeSpan.FromSeconds(0.5)); 77 Console.WriteLine("{0} prints {1}", 78 Thread.CurrentThread.Name, i); 79 } 80 } 81 } 82 } 83 }
工作原理
方法一:
當主程式啟動時,首先建立了ThreadSample類的一個物件,並提供了一個迭代次數。然後使用該物件的CounetNumbers方法啟動執行緒。該方法執行在另一個執行緒中,但是使用數字10,該數字是通過ThreadSample物件的建構函式傳入的。
方法二:
另一種傳遞資料的方式是使用Thread.Staru方法。該方法會節後一個物件,並將該物件傳遞給執行緒。為了應用該方法,線上程啟動的方法必須接收object型別的單個引數。
方法三:
接下來的方式是使用lambda表示式。這可能會導致幾個問題。例如,如果在多個lanbda表示式中使用相同的變數,他們會共享該變數。當啟動ThreadFour和ThreadFive執行緒時,他們都會列印20,因為在這兩個執行緒啟動之前變數被修改為20。
執行緒鎖
為什麼要用執行緒鎖?
所謂同步,是指多個執行緒之間存在先後執行的順序的關聯關係。如果一個執行緒必須在兩一個執行緒完成某個工作後才能繼續執行,則必須考慮如何讓讓其保持同步,以確保在系統上同時執行多個執行緒而不會出現死鎖或邏輯錯誤。
1 /*----------------------------------------------------------------------- 2 written by helio, 2019 3 ThreadSample4 4 -----------------------------------------------------------------------*/ 5 using System; 6 using System.Threading; 7 8 namespace LockSample1 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 Thread[] threads = new Thread[10]; 15 Account acc = new Account(1000); 16 for (int i = 0; i < 10;i++) 17 { 18 Thread t = new Thread(acc.AutoWithdraw); 19 t.Name = "Thread" + i; 20 threads[i] = t; 21 } 22 23 for (int i = 0; i < 10; i++) 24 threads[i].Start(); 25 Console.ReadKey(); 26 } 27 28 class Account 29 { 30 private Object lockedObj = new object(); 31 private int m_balenace; 32 Random r = new Random(); 33 public Account(int initial) 34 { 35 m_balenace = initial; 36 } 37 38 public int Withdraw(int amount) 39 { 40 Thread.Sleep(TimeSpan.FromMilliseconds(100)); 41 if (m_balenace < 0) 42 { 43 Console.WriteLine("餘額不足!"); 44 } 45 46 lock (lockedObj) 47 { 48 if (m_balenace >= amount) 49 { 50 Console.Write("{0}取款---取款前餘額:{1} 取款 {2} ", Thread.CurrentThread.Name, m_balenace, amount); 51 m_balenace -= amount; 52 Console.WriteLine("取款後餘額:{0}", m_balenace); 53 return amount; 54 } 55 else 56 { 57 return 0; 58 } 59 } 60 } 61 62 public void AutoWithdraw() 63 { 64 for (int i = 0; i < 100; i++) 65 { 66 Withdraw(r.Next(1, 100)); 67 } 68 } 69 } 70 } 71 }
閱讀原文可訪問我的個人部落格