在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
主要使用Monitor类,对一个对象进行等待和通知的操作 static void Main(string[] args) { //Task启动等待对象 object taskStartSyncRoot = new object(); //多线程等待对象 object syncRoot = new object(); //多线程全部进入等待状态对象 object parallelStartSyncRoot = new object(); lock (taskStartSyncRoot) { Task.Factory.StartNew(() => { lock (parallelStartSyncRoot) { lock (taskStartSyncRoot) { //通知Task已经启动完毕 Monitor.Pulse(taskStartSyncRoot); } Console.WriteLine("Wait all parallel task started."); //等待所有并行任务已经进行等待状态,并释放parallelStartSyncRoot锁 Monitor.Wait(parallelStartSyncRoot); lock (syncRoot) { //通知所有并行任务syncRoot已经释放 Monitor.PulseAll(syncRoot); Console.WriteLine("All syncRoot waiter notified."); } } }); //等待Task启动完毕,并释放taskStartSyncRoot对象锁 Monitor.Wait(taskStartSyncRoot); } //并行等待任务计数器,当该计数器为10时,则通知所有并行任务已经进入等待状态 int counter = 0; Parallel.For(0, 10, (i) => { lock (syncRoot) { //使用原子锁增加counter,当计数器为10时代表所有并行任务已经启动 if (Interlocked.Increment(ref counter) == 10) { lock (parallelStartSyncRoot) { //通知并行任务已经全部启动,并释放parallelStartSyncRoot锁 Monitor.Pulse(parallelStartSyncRoot); } } Console.WriteLine(string.Format("[{0}] Waiting For syncRoot notify.", i)); //等待syncRoot通知,并释放syncRoot锁 Monitor.Wait(syncRoot); Console.WriteLine(string.Format("[{0}] syncRoot notify received.", i)); } }); Console.Read(); } 该程序是个多线程的应用,程序的逻辑将会严格按照以下顺序执行 (1)[主线程] 启动Task线程,等待taskStartSyncRoot,暂时释放syncRoot锁 (2)[TASK线程] 锁住parallelStartSyncRoot 和 taskStartSyncRoot(这里会等待主线程进入Wait状态),通知taskStartSyncRoot已经启动 (3)[TASK线程] 等待parallelStartSyncRoot,暂时释放parallelStartSyncRoot锁 (4)[Parallel子线程] Parallel并行任务启动,并且等待syncRoot,暂时释放syncRoot锁 (5)[最后一个Parallel子线程] 通知parallelStartSyncRoot已经全部启动 (6)[TASK线程] 等待锁syncRoot (7)[最后一个Parallel子线程] 等待syncRoot,这时会暂时释放syncRoot锁 (8)[TASK线程] 获得syncRoot锁,并且通知(Monitor.PulseAll)所有syncRoot等待者(所有并行任务)。 程序的执行结果: 总结:要理解该多线程程序,必须要理解这三个锁对象的操作,以及通知机制的应用,从而可以让Task和多个并行任务有序的进行执行,大家在这里需要掌握几个知识点: (1)在Monitor.Wait对象时必须获得目标对象的锁,以确保进入临界状态 (2)Monitor.Wait方法调用时,会将目标对象锁释放,在Wait完成时会重新获得该锁
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论