不废话,废话都在代码里
/********************************************** * Copyright(C),2013-2014 * FileName : 多线程整理文件 * Author : ShintoRuan * Date : 2014/1/10 * Description : 练习多线程总结 * Others : * History : ***********************************************/ namespace Multithreading { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; class Program { static void Main(string[] args) { ThreadControlDemo.Run(); Console.ReadKey(); } } }
1 /******************************************************** 2 * Copyright(C),2013-2014, 3 * FileName : 4 * Author : ShintoRuan 5 * Date : 6 * Description : 7 * Others : 8 * History : 9 ********************************************************/ 10 namespace Multithreading 11 { 12 using System; 13 using System.Collections.Generic; 14 using System.Diagnostics; 15 using System.Linq; 16 using System.Text; 17 using System.Threading; 18 19 internal class ThreadControlDemo 20 { 21 public static void Run() 22 { 23 ThreadControlDemo demo = new ThreadControlDemo(); 24 Console.WriteLine("程序开始"); 25 //demo.Start(); 26 //demo.Sleep(); 27 //demo.Abort(); 28 //demo.SuspendAndResume(); 29 //demo.Join(); 30 31 //资源争用 32 demo.ResourceContention(); 33 34 Console.WriteLine("程序结束"); 35 } 36 37 # region Start 38 39 /// <summary> 40 /// 创建并启用线程 41 /// </summary> 42 public void Start() 43 { 44 Thread myThread1 = new Thread(new ThreadStart(DemoMethod.Print)); 45 myThread1.Start(); 46 Thread myThread2 = new Thread(new ParameterizedThreadStart(DemoMethod.Print)); 47 myThread2.Start("x"); 48 Console.WriteLine("End:StartDemo"); 49 } 50 #endregion 51 52 #region Sleep 53 54 /// <summary> 55 /// 线程睡眠 56 /// </summary> 57 public void Sleep() 58 { 59 Thread myThread = new Thread(new ParameterizedThreadStart(DemoMethod.Print)); 60 myThread.Start("x"); 61 //睡觉2000毫秒 62 Thread.Sleep(2000); 63 Console.WriteLine("我睡了多久了?"); 64 } 65 66 #endregion 67 68 #region Abort 69 70 /// <summary> 71 /// 线程终止 72 /// </summary> 73 public void Abort() 74 { 75 Thread myThread1 = new Thread(new ThreadStart(DemoMethod.Print)); 76 myThread1.Start(); 77 Thread.Sleep(30); 78 79 //通过引发异常来终止指定线程 80 myThread1.Abort(); 81 82 Console.WriteLine("线程被终止"); 83 } 84 #endregion 85 86 #region Suspend And Resume 87 88 /// <summary> 89 /// 挂起与解挂 90 /// </summary> 91 /// <remarks> 92 /// 这下两个方法已过时,容易导致程序死锁。 93 /// (使用Mutex类的Wait...方法代替)未验证-网上说安全与性能之间的取舍, 94 /// 当你确定不会出现死锁等问题时,放心大胆的用,就像使用指针一样,C#也是不推荐使用的 95 /// (难怪我到现在都没用过,C里面的核心啊,改天研究下C#里的指针使用) 96 /// DemoMethod.Print为一个Console的方法、当挂起后,这是主线程再调用Console就会出现死锁 97 /// 因为myThread线程占用了输出窗口、在它还没运行完时,被挂起了,但没有释放该资源,这时 98 /// 主线程请求该资源,得不到请求,线程重新进入就绪队列,等待资源,直到myThread释放该资源 99 /// 而myThread线程则在等待主线程给它解挂,所以就死锁了 100 /// </remarks> 101 public void SuspendAndResume() 102 { 103 Thread myThread = new Thread(new ThreadStart(DemoMethod.Print)); 104 myThread.Start(); 105 106 Console.WriteLine("线程挂起"); 107 //myThread.Suspend(); 108 109 //Console.WriteLine("死锁了没"); 110 Thread.Sleep(1000);//暂停1秒 111 112 Console.WriteLine("线程解挂"); 113 myThread.Resume(); 114 } 115 116 #endregion 117 118 #region Join 119 120 /// <summary> 121 /// Join方法 122 /// </summary> 123 /// <remarks> 124 /// 阻塞调用线程、直到myThread结束或规定时间后 125 /// </remarks> 126 public void Join() 127 { 128 Thread myThread1 = new Thread(new ThreadStart(DemoMethod.Print)); 129 130 Thread myThread2 = new Thread(new ParameterizedThreadStart(DemoMethod.Print)); 131 myThread1.Start(); 132 133 myThread1.Join(); 134 135 myThread2.Start("x"); 136 137 //输出结果为,myThread1执行完,myThread2开始执行 138 } 139 #endregion 140 141 #region 多线程资源争用问题 142 143 /// <summary> 144 /// 资源争用 145 /// </summary> 146 /// <remarks> 147 /// 资源争用问题是多线程常见问题,当资源有限时,争用开始显现, 148 /// 特别是人多肉少时,更为突出,(解决方案:操作系统中的资源分配) 149 /// </remarks> 150 public void ResourceContention() 151 { 152 Thread myThread1 = new Thread(new ParameterizedThreadStart(new SampleTask().RaceCondition)); 153 Thread myThread2 = new Thread(new ParameterizedThreadStart(new SampleTask().RaceCondition)); 154 Thread myThread3 = new Thread(new ParameterizedThreadStart(new SampleTask().RaceCondition)); 155 StateObject resource = new StateObject(); 156 myThread1.Start(resource); 157 myThread2.Start(resource); 158 myThread3.Start(resource); 159 } 160 #endregion 161 } 162 163 internal class DemoMethod 164 { 165 /// <summary> 166 /// 打印1000次 167 /// </summary> 168 public static void Print() 169 { 170 171 for (int i = 0; i < 1000; i++) 172 { 173 //if (i==88) 174 //{ 175 // //在这里挂起线程,Print会释放掉它所占用的控制台资源 176 // Thread.CurrentThread.Suspend(); 177 //} 178 Console.Write("_"); 179 } 180 181 } 182 183 /// <summary> 184 /// 打印指定文字 185 /// </summary> 186 /// <param name="x">指定文字</param> 187 public static void Print(object x) 188 { 189 for (int i = 0; i < 1000; i++) 190 { 191 Console.Write(x.ToString()); 192 } 193 } 194 } 195 196 #region 线程问题 197 198 199 /// <summary> 200 /// 争用条件测试 201 /// </summary> 202 public class SampleTask 203 { 204 public void RaceCondition(object o) 205 { 206 //断言:但第一个表达式为false时,引发异常 207 Trace.Assert(o is StateObject, "o must be of type StateObject"); 208 StateObject state = o as StateObject; 209 210 int i = 0; 211 while (true) 212 { 213 // 在被争用资源前加入Lock,使得资源不可被同时访问 214 // lock (state) 215 // { 216 state.ChangeState(i++); 217 // } 218 } 219 } 220 } 221 222 /// <summary> 223 /// 被争用条件 224 /// </summary> 225 public class StateObject 226 { 227 private int state = 5; 228 229 public void ChangeState(int loop) 230 { 231 if (state == 5) 232 { 233 state++; 234 235 Trace.Assert(state == 6, "Race condition occurred after " + loop + " loops"); 236 237 } 238 state = 5; 239 } 240 } 241 #endregion 242 }
懒人写不出好博客,这种纯代码我自己都懒的看,全当以后回忆用
2014/1/11,在这个孤单的日子里,又把线程状态搞了下,贴到这里来,那么多线程算差不多了
当然,后面还有很多, 留着以后研究了。
前台线程和后台线程的区别:直观点说,当父线程结束时,需等待所有前台进程结束...
1 /******************************************************** 2 * Copyright(C),2013-2014,iFLYTEK 3 * FileName : 4 * Author : ShintoRuan 5 * Date : 6 * Description : 7 * Others : 8 * History : 9 ********************************************************/ 10 11 namespace Multithreading 12 { 13 using System; 14 using System.Collections.Generic; 15 using System.Linq; 16 using System.Text; 17 using System.Threading; 18 19 public class ThreadStateDemo 20 { 21 /// <summary> 22 /// 定义一个全局变量,用于记录主线程状态 23 /// </summary> 24 public static Thread threadBackup { get; set; } 25 26 /// <summary> 27 /// 该测试主入口 28 /// </summary> 29 public static void Run() 30 { 31 ThreadStateDemo test = new ThreadStateDemo(); 32 test.StateTest(); 33 } 34 35 /// <summary> 36 /// 主方法 37 /// </summary> 38 public void StateTest() 39 { 40 threadBackup = Thread.CurrentThread; 41 42 Thread myThread1 = new Thread(new ThreadStart(TestTarget.print)); 43 44 Thread myThread2 = new Thread(new ThreadStart(TestTarget.print)); 45 46 Thread myThread3 = new Thread(new ThreadStart(TestTarget.IsBackGroundTest)); 47 48 Console.WriteLine("开始前:{0}",myThread1.ThreadState); 49 myThread1.Start(); 50 Console.WriteLine("开始时:{0}", myThread1.ThreadState); 51 Thread.Sleep(1000); 52 Console.WriteLine("睡眠时:{0}", myThread1.ThreadState); 53 Thread.Sleep(2000); 54 55 //这种方法无法打印出suspendRequest状态, 56 Console.WriteLine("挂起时:{0}", myThread1.ThreadState); 57 myThread1.Resume(); 58 Console.WriteLine("解挂后:{0}", myThread1.ThreadState); 59 myThread1.Join(); 60 61 //=======================Start:myThread2========================== 62 63 myThread2.Start(); 64 myThread2.Abort(); 65 Console.WriteLine("Abort瞬间:{0}",myThread2.ThreadState); 66 Thread.Sleep(50); 67 Console.WriteLine("Abort完成:{0}", myThread2.ThreadState); 68 69 //======================IsbackGround=============================== 70 myThread3.IsBackground = false; //默认为false 71 myThread3.Name = myThread3.IsBackground ? "后台线程" : "前台线程"; 72 myThread3.Start(); 73 Thread.CurrentThread.Abort(); 74 } 75 } 76 77 /// <summary> 78 /// 目标类 79 /// </summary> 80 public class TestTarget 81 { 82 /// <summary> 83 /// 打印+号 84 /// </summary> 85 public static void print() 86 { 87 for (int i = 0; i < 1; i++) 88 { 89 //在这暂停2秒 90 if (i==0) 91 { 92 Thread.Sleep(2000); 93 } 94 95 //到这被挂起,等待解挂 96 if (i==0) 97 { 98 Thread.CurrentThread.Suspend(); 99 } 100 101 //在这缓冲一下,防止下面方法在myThread1.Join()之前运行 102 if (i==0) 103 { 104 Thread.Sleep(30); 105 } 106 107 //打印主线程被Join后的状态 108 if (i==0) 109 { 110 Console.WriteLine("Join后:{0}",ThreadStateDemo.threadBackup.ThreadState); 111 } 112 113 //终于可以打印加号了 114 Console.WriteLine("+"); 115 116 } 117 118 } 119 120 public static void IsBackGroundTest() 121 { 122 Thread.Sleep(2000); 123 Console.WriteLine("2秒后你将得到救赎!"); 124 } 125 126 } 127 }