向线程传递参数
代码中实现了三种不一样的方法向线程中传递参数。
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 }
阅读原文可访问个人我的博客函数