多线程学习(二)

  向线程传递参数
  代码中实现了三种不同的方法向线程中传递参数。
 

 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 }

阅读原文可访问我的个人博客

猜你喜欢

转载自www.cnblogs.com/Helio/p/11079408.html