C#中 Thread类的使用
来源:互联网 发布:淘宝网购物车登录界面 编辑:程序博客网 时间:2024/05/16 17:09
基本的 Thread 框架
基本的 Thread 程序结构,由工作函数,start 和 join 组成
Thread类是比较常用的一个类,这里总结了一些基本的使用方法和程序示例,以备以后查用。
https://msdn.microsoft.com/zh-cn/library/system.threading.thread.aspx
using System;using System.Threading;// Simple threading scenario: Start a static method running// on a second thread.public class ThreadExample{ // The ThreadProc method is called when the thread starts. // It loops ten times, writing to the console and yielding // the rest of its time slice each time, and then ends. public static void ThreadProcA() { for (int i = 0; i < 10; i++) { Console.WriteLine("ThreadProc A: {0}", i); Thread.Sleep(0); } } public static void ThreadProcB() { for (int i = 0; i < 10; i++) { Console.WriteLine("ThreadProc B: {0}", i); // Yield the rest of the time slice. Thread.Sleep(0); } } public static void Main() { Console.WriteLine("Main thread: Start a second thread."); // The constructor for the Thread class requires a ThreadStart // delegate that represents the method to be executed on the // thread. C# simplifies the creation of this delegate. Thread t = new Thread(new ThreadStart(ThreadProcA)); Thread t1 = new Thread(new ThreadStart(ThreadProcB)); // Start ThreadProc. Note that on a uniprocessor, the new // thread does not get any processor time until the main thread // is preempted or yields. Uncomment the Thread.Sleep that // follows t.Start() to see the difference. t.Start(); t1.Start(); //Thread.Sleep(0); for (int i = 0; i < 4; i++) { Console.WriteLine("Main thread: Do some work."); Thread.Sleep(0); } Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends."); t.Join(); t1.Join(); Console.WriteLine("Main thread: ThreadProc.Join has returned. Press Enter to end program.\n"); Console.ReadLine(); }}
这仅仅是一个创建两个线程的例子,但并不太符合实际应用的情况此时的输出结果A 与 B 随机打印。
使用 Mutex
使用多线程,无法避免的一定是线程间的同步互斥,及对于共享资源的访问,这里的Mutex便是线程互斥的一种方式。当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。使用Mutex 时,它只向一个线程开放访问权。 如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体
https://msdn.microsoft.com/zh-cn/library/System.Threading.Mutex(v=vs.80).aspx
using System;using System.Threading;// Simple threading scenario: Start a static method running// on a second thread.public class ThreadExample{ private static Mutex m_Mutex = new Mutex(); // The ThreadProc method is called when the thread starts. // It loops ten times, writing to the console and yielding // the rest of its time slice each time, and then ends. public static void ThreadProcA() { m_Mutex.WaitOne(); for (int i = 0; i < 10; i++) { Console.WriteLine("ThreadProc A: {0}", i); Thread.Sleep(0); } m_Mutex.ReleaseMutex(); } public static void ThreadProcB() { m_Mutex.WaitOne(); for (int i = 0; i < 10; i++) { Console.WriteLine("ThreadProc B: {0}", i); // Yield the rest of the time slice. Thread.Sleep(0); } m_Mutex.ReleaseMutex(); } public static void Main() { Console.WriteLine("Main thread: Start a second thread."); // The constructor for the Thread class requires a ThreadStart // delegate that represents the method to be executed on the // thread. C# simplifies the creation of this delegate. Thread t = new Thread(new ThreadStart(ThreadProcA)); Thread t1 = new Thread(new ThreadStart(ThreadProcB)); // Start ThreadProc. Note that on a uniprocessor, the new // thread does not get any processor time until the main thread // is preempted or yields. Uncomment the Thread.Sleep that // follows t.Start() to see the difference. t.Start(); t1.Start(); //Thread.Sleep(0); m_Mutex.WaitOne(); for (int i = 0; i < 4; i++) { Console.WriteLine("Main thread: Do some work."); Thread.Sleep(0); } m_Mutex.ReleaseMutex(); Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends."); t.Join(); t1.Join(); Console.WriteLine("Main thread: ThreadProc.Join has returned. Press Enter to end program.\n"); Console.ReadLine(); }}
此时的输出结果固定。
使用 Monitor
Monitor 是线程间同步互斥的另一种方式,与Mutex最直接的不同是它是与对象关联的。相似点确实很多,都可以对一个临界区进行保护,并且成对出现。
Monitor 类通过向单个线程授予对象锁来控制对对象的访问。 对象锁提供限制访问 代码块(通常称为临界区)的能力。当一个线程拥有对象的锁时,其他任何线程都不能获取该锁。
Monitor 具有以下功能:
- 它根据需要与某个对象相关联。
- 它是未绑定的,也就是说可以直接从任何上下文调用它。
- 不能创建 Monitor 类的实例。
同时需要注意的是,Monitor.Enter()函数传入的是一个对象,如果传入了一个简单类型,它会引发装箱操作,这时它所加锁的是一个新的对象。
https://msdn.microsoft.com/zh-cn/library/de0542zz(v=vs.80).aspx
主要关注其中 3个线程函数: ThreadProcAdd, ThreadProcRemove, ThreadProcShow。
主要的意图是在程序运行中3个线程操作同一个队列,进行多次的读,写和删除,每一次操作一组5个数据,这一组数据为不可分割的,。
using System;using System.Collections;using System.Threading;namespace MonitorCS2{ /// <summary> /// Summary description for Class1. /// </summary> class MonitorSample { //Define the queue to safe thread access. private static Queue m_inputQueue = new Queue(); public MonitorSample() { } //Add an element to the queue and obtain the monitor lock for the queue object. public void AddElement(object qValue) { //Lock the queue. Monitor.Enter(m_inputQueue); //Add element m_inputQueue.Enqueue(qValue); //Unlock the queue. Monitor.Exit(m_inputQueue); } //Try to add an element to the queue. //Add the element to the queue only if the queue object is unlocked. public bool AddElementWithoutWait(object qValue) { //Determine whether the queue is locked if (!Monitor.TryEnter(m_inputQueue)) return false; m_inputQueue.Enqueue(qValue); Monitor.Exit(m_inputQueue); return true; } //Try to add an element to the queue. //Add the element to the queue only if during the specified time the queue object will be unlocked. public bool WaitToAddElement(object qValue, int waitTime) { //Wait while the queue is locked. if (!Monitor.TryEnter(m_inputQueue, waitTime)) return false; m_inputQueue.Enqueue(qValue); Monitor.Exit(m_inputQueue); return true; } //Delete all elements that equal the given object and obtain the monitor lock for the queue object. public void DeleteElement(object qValue) { //Lock the queue. Monitor.Enter(m_inputQueue); int counter = m_inputQueue.Count; while (counter > 0) { //Check each element. object elm = m_inputQueue.Dequeue(); if (!elm.Equals(qValue)) { m_inputQueue.Enqueue(elm); } --counter; } //Unlock the queue. Monitor.Exit(m_inputQueue); } //Print all queue elements. public void PrintAllElements() { //Lock the queue. Monitor.Enter(m_inputQueue); IEnumerator elmEnum = m_inputQueue.GetEnumerator(); while (elmEnum.MoveNext()) { //Print the next element. Console.WriteLine(elmEnum.Current.ToString()); } //Unlock the queue. Monitor.Exit(m_inputQueue); } public static void ThreadProcAdd() { for (int j = 0; j < 5; j++) { try { //Lock the queue. Monitor.Enter(m_inputQueue); for (int i = 0; i < 5; i++) { //Add element m_inputQueue.Enqueue(i); Thread.Sleep(50); Console.WriteLine("ThreadProc Add: {0} per 50 ms", i); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { //Unlock the queue. Monitor.Exit(m_inputQueue); } Thread.Sleep(200); } } public static void ThreadProcShow() { for (int i = 0; i < 20; i++) { try { //Lock the queue. Monitor.Enter(m_inputQueue); IEnumerator elmEnum = m_inputQueue.GetEnumerator(); Console.WriteLine("Show: "); while (elmEnum.MoveNext()) { //Print the next element. Console.Write(elmEnum.Current.ToString() + ", "); } Console.WriteLine(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { //Unlock the queue. Monitor.Exit(m_inputQueue); } Thread.Sleep(100); } } public static void ThreadProcRemove() { for (int j = 0; j < 5; j++) { try { //Lock the queue. Monitor.Enter(m_inputQueue); int counter = m_inputQueue.Count; while (counter > 0) { //Check each element. object elm = m_inputQueue.Dequeue(); Console.WriteLine("ThreadProc remove: {0} per 50 ms", (int)elm); Thread.Sleep(50); --counter; } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { //Unlock the queue. Monitor.Exit(m_inputQueue); } Thread.Sleep(200); } } static void Main(string[] args) { Thread ta = new Thread(new ThreadStart(ThreadProcAdd)); Thread tr = new Thread(new ThreadStart(ThreadProcRemove)); Thread ts = new Thread(new ThreadStart(ThreadProcShow)); ta.Start(); tr.Start(); ts.Start(); ta.Join(); tr.Join(); ts.Join(); Console.WriteLine("Main thread: ThreadProc.Join has returned. Press Enter to end program.\n"); Console.ReadLine(); } }}
测试结果:
从测试结果可以看出,插入操作和删除操作都是整体出现的,并没有被打断的迹象。
0 0
- C#中 Thread类的使用
- c#中Thread的基本使用
- C#中Thread.Time的使用
- C#中Thread.Time的使用
- JAVA或C#中Thread.Sleep()的使用
- C#中Thread类应用
- C# Thread类的应用
- C# Thread类的应用
- C# Thread类的应用
- C#中Thread与ThreadPool的比较
- C# 多线程的使用(Thread)-初识多线程
- C# thread的join方法使用解析
- C#多线程Thread.Abort的使用
- Thread类的使用
- Thread类的使用
- Thread类的使用
- Thread类的使用
- Thread类的使用
- html调整img的水平垂直位置
- Eclipse查看Java源码的方式
- javax.tools.Diagnostic 类使用示例
- C++ & VB.NET & VB 过程函数结构
- LeetCode:Majority Element
- C#中 Thread类的使用
- 异常详细信息: System.Data.SqlClient.SqlException:用户 'IIS APPPOOL\DefaultAppPool' 登录失败解决办法
- RXTX for JAVA 串口编程实例
- DOMImplementation
- spring+mybatis
- Oracle Flash Storage System新版手册集
- Dubbo监控中心安装与Dubbo管理控制台安装
- 利用junit4单元测试要点
- ios下 KeyChain 的研究