向線程傳遞參數
代碼中實現了三種不一樣的方法向線程中傳遞參數。
git
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。github
線程鎖
爲何要用線程鎖?
所謂同步,是指多個線程之間存在前後執行的順序的關聯關係。若是一個線程必須在兩一個線程完成某個工做後才能繼續執行,則必須考慮如何讓讓其保持同步,以確保在系統上同時運行多個線程而不會出現死鎖或邏輯錯誤。
dom
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 }
閱讀原文可訪問個人我的博客函數