C# 线程同步之Moitor实现线程的顺序执行
有这么个场景,A线程执行A函数,B线程执行B函数,C线程执行C函数,并且ABC函数要按顺序执行,如何实现
我们可以利用Monitor和ConcurrentDictionary来实现。
Monitor是比lock更灵活操作,再.net中,lock在中间语言会被翻译成Monitor;
ConcurrentDictionary是线程安全的字典。
实现一个类:
/// <summary> /// 顺序线程 线程按执行顺序 /// </summary> public class OrderedThread { #region 静态字段 /// <summary> /// 当前的线程循序序号 /// </summary> private static int _inner_orderedID = 0; /// <summary> /// 当前的线程的队列 /// </summary> private static ConcurrentDictionary<int, OrderedThread> inner_readyThreadList = new ConcurrentDictionary<int, OrderedThread>(); /// <summary> /// 线程锁 /// </summary> private static object _objLock = new object(); #endregion #region 成员字段 /// <summary> /// 处理的委托 /// </summary> private Action<int> _inner_action = null; #endregion #region 构造函数 /// <summary> /// 构造函数 /// </summary> /// <param name="handling">处理的委托</param> public OrderedThread(Action<int> handling) { this._inner_action = handling; } #endregion #region 开始执行线程 /// <summary> /// 开始执行线程 /// </summary> public void Start() { //添加到就绪集合中 inner_readyThreadList.AddOrUpdate(_inner_orderedID++, this, (key, vlaue) => { return this; }); Thread th = new Thread(() => { bool isEnter = Monitor.TryEnter(_objLock); if (isEnter) { //如果就绪队列中有要执行的线程 while (inner_readyThreadList.Count() > 0) { //找到起始的最小值 int minIndex = inner_readyThreadList.Keys.Min(); //绪队列中线程执行 inner_readyThreadList[minIndex]._inner_action.Invoke(minIndex); //移除执行完成的 OrderedThread orderedThreadTmp = null; inner_readyThreadList.TryRemove(minIndex, out orderedThreadTmp); } Monitor.Exit(_objLock); } }); th.SetApartmentState(ApartmentState.STA); th.IsBackground = true; th.Start(); } #endregion }
我们的业务类:
public class PrintClass { public void PrintOne() { Console.WriteLine("one"); } public void PrintTwo() { Console.WriteLine("two"); } public void PrintThree() { Console.WriteLine("three"); } }
调用:
class Program { static void Main(string[] args) { PrintClass p=new PrintClass(); OrderedThread firstThread = new OrderedThread((o)=> { p.PrintOne(); Thread.Sleep(5000); }); OrderedThread SecondThread = new OrderedThread((o) => { p.PrintTwo(); }); OrderedThread ThirdThread = new OrderedThread((o) => { p.PrintThree(); }); firstThread.Start(); ThirdThread.Start(); SecondThread.Start(); Console.ReadLine(); } }
其中:Start的顺序就是要执行的顺序。