如何做好网站内更新,东莞南城,网站首页 psd,做公司官网步骤一. Thread及其五大方法 Thread是.Net最早的多线程处理方式#xff0c;它出现在.Net1.0时代#xff0c;虽然现在已逐渐被微软所抛弃#xff0c;微软强烈推荐使用Task(后面章节介绍)#xff0c;但从多线程完整性的角度上来说#xff0c;我们有必要了解下N年前多线程的是怎么…一. Thread及其五大方法 Thread是.Net最早的多线程处理方式它出现在.Net1.0时代虽然现在已逐渐被微软所抛弃微软强烈推荐使用Task(后面章节介绍)但从多线程完整性的角度上来说我们有必要了解下N年前多线程的是怎么处理的以便体会.Net体系中多线程处理方式的进化。 Thread中有五大方法分别是Start、Suspend、Resume、Intterupt、Abort ①.Start开启线程 ②.Suspend暂停线程 ③.Resume恢复暂停的线程 ④.Intterupt中断线程(会抛异常提示线程中断) ⑤.Abort销毁线程 这五大方法使用起来也比较简单下面贴一段代码体会一下如何使用即可。 在这里补充一下在该系列中很多测试代码中看到TestThread0、TestThread、TestThread2分别对应无参、一个参数、两个参数的耗时方法代码如下 View Code 二. 从源码角度分析Thread类
(1) 分析Thread类的源码发现其构造函数有两类分别是ThreadStart和ParameterizedThreadStart类 其中 ①ThreadStart类是无参无返回值的委托。 ②ParameterizedThreadStart类,是有一个object类型参数但无返回值的委托.
使用方法 ①针对ThreadStart类 ThreadStart myTs () TestThread(name); 然后再把myTs传入Thread的构造函数中 ②针对ParameterizedThreadStart类ParameterizedThreadStart myTs o this.TestThread(o.ToString()); 然后再把myTs传入Thread的构造函数中 注该方式存在拆箱和装箱的转换问题不建议这么使用 通用写法 Thread t new Thread(() { Console.Write(333); }); t.Start(); 无须考虑Thread的构造函数,也不需要考虑Start的时候传参直接使用(){}的形式解决一切问题。 (二) 前台进程和后台进程IsBackground属性 ①前台进程,Thread默认为前台线程程序关闭后线程仍然继续直到计算完为止 ②后台进程,将IsBackground属性设置为true即为后台进程主线程关闭所有子线程无论运行完否都马上关闭
(三) 线程等待Join方法 利用Join方法实现主线程等待子线程,当多个子线程进行等待的时候只能通过for循环来实现 下面贴一下这三块设计到的代码 View Code (四). 扩展Thread实现线程回调 三. 数据槽-线程可见性 背景为了解决多线程竞用共享资源的问题引入数据槽的概念即将数据存放到线程的环境块中使该数据只能单一线程访问.属于线程空间上的开销 下面的三种方式是解决多线程竞用共享资源的通用方式 ①AllocateNamedDataSlot命名槽位和AllocateDataSlot未命名槽位 解决线程竞用资源共享问题。 (PS:在主线程上设置槽位使该数据只能被主线程读取其它线程无法访问) private void button10_Click(object sender, EventArgs e){#region 01-AllocateNamedDataSlot命名槽位{var d Thread.AllocateNamedDataSlot(userName);//在主线程上设置槽位使该数据只能被主线程读取其它线程无法访问Thread.SetData(d, ypf);//声明一个子线程var t1 new Thread(() {Console.WriteLine(子线程中读取数据{0}, Thread.GetData(d));});t1.Start();//主线程中读取数据Console.WriteLine(主线程中读取数据{0}, Thread.GetData(d));}#endregion#region 02-AllocateDataSlot未命名槽位{var d Thread.AllocateDataSlot();//在主线程上设置槽位使该数据只能被主线程读取其它线程无法访问Thread.SetData(d, ypf);//声明一个子线程var t1 new Thread(() {Console.WriteLine(子线程中读取数据{0}, Thread.GetData(d));});t1.Start();//主线程中读取数据Console.WriteLine(主线程中读取数据{0}, Thread.GetData(d));}#endregion} ②利用特性[ThreadStatic] 解决线程竞用资源共享问题 (PS:在主线程中给ThreadStatic特性标注的变量赋值则只有主线程能访问该变量) ③利用ThreadLocal线程的本地存储 解决线程竞用资源共享问题线程可见性 (PS: 在主线程中声明ThreadLocal变量并对其赋值则只有主线程能访问该变量) 四. 内存栅栏-线程共享资源
背景当多个线程共享一个变量的时候在Release模式的优化下子线程会将共享变量加载的cup Cache中导致主线程不能使用该变量而无法运行。
解决方案 ①不要让多线程去操作同一个共享变量,从根本上解决这个问题。 ②利用MemoryBarrier方法进行处理,在此方法之前的内存写入都要及时从cpu cache中更新到 memory在此方法之后的内存读取都要从memory中读取而不是cpu cache。 ③利用VolatileRead/Write方法进行处理。 1 private void button11_Click(object sender, EventArgs e)2 {3 #region 01-默认情况(Release模式主线程不能正常运行)4 //{5 // var isStop false;6 // var t new Thread(() 7 // {8 // var isSuccess false;9 // while (!isStop)
10 // {
11 // isSuccess !isSuccess;
12 // }
13 // Console.WriteLine(子线程执行成功);
14 // });
15 // t.Start();
16
17 // Thread.Sleep(1000);
18 // isStop true;
19
20 // t.Join();
21 // Console.WriteLine(主线程执行结束);
22 //}
23 #endregion
24
25 #region 02-MemoryBarrier解决共享变量Release模式下可以正常运行
26 //{
27 // var isStop false;
28 // var t new Thread(()
29 // {
30 // var isSuccess false;
31 // while (!isStop)
32 // {
33 // Thread.MemoryBarrier();
34
35 // isSuccess !isSuccess;
36 // }
37 // Console.WriteLine(子线程执行成功);
38 // });
39 // t.Start();
40
41 // Thread.Sleep(1000);
42 // isStop true;
43
44 // t.Join();
45 // Console.WriteLine(主线程执行结束);
46 //}
47 #endregion
48
49 #region 03-VolatileRead解决共享变量Release模式下可以正常运行
50 {
51 var isStop 0;
52 var t new Thread(()
53 {
54 var isSuccess false;
55 while (isStop 0)
56 {
57 Thread.VolatileRead(ref isStop);
58
59 isSuccess !isSuccess;
60 }
61 Console.WriteLine(子线程执行成功);
62 });
63 t.Start();
64
65 Thread.Sleep(1000);
66 isStop 1;
67
68 t.Join();
69 Console.WriteLine(主线程执行结束);
70 }
71 #endregion
72
73
74 }