C#多线程基础
线程基础 一个进程由若干个线程组成,线程是程序执行的基本原子单位。线程是"进程"中某个单一顺序的控制流,线程是进程中的一个基本执行流,每个线程都有自己专属的寄存器(程序计数器、栈指针等),代码共享区,不同的线程可以执行同样的方法。 ????多线程可以实现并行处理,可以避免某项任务长时间占用CPU时间,需要注意的是,多线程程序对于效率,应该根据任务不同的要求来选择。 线程的命名空间System.Threading ????Thread类是线程中最重要的一个,Thread类提供了创建并控制线程,设置其优先级并获取其状态的方法。 ????Thread类的声明: class ThreadSimple { //静态线程函数 public static void ThreadMethodExample() { } } //调用静态方法 Thread threadSimple = new Thread(ThreadSimple.ThreadMethodExample); 或: void ThreadMethodExample() { } //调用静态方法 //Thread threadSimple = new Thread(ThreadSimple.ThreadMethodExample); Thread(ThreadStart(ThreadMethodExample)); }
public static void MethodSubB() { do lock(lockExample) i-=1; Console.WriteLine("线程2开始,共享数据为:i={0}",i); Thread.Sleep(2000); //线程A休眠2秒 Console.WriteLine("线程2结束,共享数据值i={0}",1)"> } } while (true); } 3.Mutex类同步数据访问
只向某个线程授予对共享资源的独占访问权,如果一个获取了互斥体,那么想要获取该互斥体的其他线程将被挂起,直到这个线程释放该互 斥体。
线程可以使用Mutex.WaitOne()方法释放这个对象,而在此期间,其他想要获取这个Mutex对象的线程都只能等待。 ? 4.Monitor类同步数据访问数
Monitor类用于锁定对象,一个线程只有得到这把锁才能对该对象进行操作,对象锁保证了在可能引起混乱的情况下,一个时刻只有一个线程可以访问这个对象。 Monitor必须和一个具体的对象相关联,但由于它是一个静态类,所以不能使用它来定义对象,而且它的所有方法都是静态的,不能使用对象来引用。 当一个线程调用Monitor.Enter()方法锁定对象时,这个对象就归它所有了,其他线程想要访问这个对象,只有等待它调用Monitor.Exit()方法释放锁。 ????????????Monitor类主要成员 ?
? private static Object sObjectA = Object(); Object sObjectB = void DemoA() { if(Monitor.TryEnter(sObjectA,1000)) { Thread.Sleep(1000); if (Monitor.TryEnter(sObjectB,2000)) { Monitor.Exit(sObjectB); } else { Console.WriteLine("TryEnter SObjectB超时..."); } Monitor.Exit(sObjectA); } "执行DemoA"); } void DemoB() { Monitor.Exit(sObjectA); } "TryEnter SObjectA超时..."); } Monitor.Exit(sObjectB); } "执行DemoB"); } void Main(string[] args) { Thread threadA = Thread(DemoA); Thread threadB = Thread(DemoB); threadA.Start(); threadB.Start(); Thread.Sleep(4000); "线程结束"); } ? 5.带参数线程 在不传递参数的情况下,可以使用ThreadStart代理来执行函数,如果要传递参数给执行函数,则可使用ParameterizedThreadStart代理来链接函数 Thread类的4个重载的构造函数 ? 1.Thread(ThreadStart)[初始化Thread类的新实例] 2.Thread(ParameterizedThreadStart) [初始化Thread类的新实例,指定允许对象在线程启动时传递给线程的委托] 3.Thread(ParameterizedThreadStart,Int32) 4.Thread(ThreadStart,Int32) [初始化Thread类的新实例,并指定线程的最大堆栈] 实例: ThreadDemo { int paraA,paraB; void MethodDemo() { "paraA={0},paraB={1}",paraA,paraB); } void Print(object obj) { "传入的参数是{0}",obj.ToString()); } } string[] args) { ThreadDemo A = ThreadDemo(); A.paraA = 2; A.paraB = 3; ThreadStart(A.MethodDemo)); threadA.Start(); ParameterizedThreadStart(ThreadDemo().Print)); threadB.Start(" 这是传入的参数"); ? ? Console.Write("Press any key to continue..."); Console.ReadKey(); } ? 6.线程池ThreadPool 线程池是可以在后台执行多个任务的线程集合,这使得主线程可以自由地异步执行其他任务。一旦池中的某个线程任务完成,它将返回到等待线程队列中等待在此被使用。线程池线程都是后台线程。 以下情况应该使用单独的线程不宜使用线程池 1.线程需要指定优先级 2.线程执行的时间较长 3.线程在单独的线程apartment中 4.在线程执行的过程中对线程存在操作 static void MethodA(object num) { int QueueNum = (int)num; Console.WriteLine("线程号:{0}",QueueNum); //输出空行,为了美观 Console.WriteLine(); } string[] args) { for (int i = 0; i < 5; i++) { //在线程池中创建线程池线程来执行指定的方法(用WaitCallBack来表示),并将此线程排入线程池的队列等待执行 ThreadPool.QueueUserWorkItem(WaitCallback(MethodA),i); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |