多线程中的ManualResetEvent

简介: 先来看一下简单的多线程控制台程序:using System;using System.Threading;namespace ManualResetEventStudy{    class ThreadClass    {        static void t1()        {    ...

先来看一下简单的多线程控制台程序:

using  System;
using  System.Threading;

namespace  ManualResetEventStudy
{

    
class  ThreadClass
    {
        
static   void  t1()
        {
            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t1的x: "   +  x);
            }
        }

        
static   void  t2()
        {
            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t2的x: "   +  x);
            }
        }

        
static   void  Main( string [] args)
        {
            Thread thrd1 
=   new  Thread(t1);
            thrd1.Start();

            Thread thrd2 
=   new  Thread(t2);
            thrd2.Start();


            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" 主线程中的x: "   +  x);
            }

            Console.Read();
        }       
    }
}

 入口方法Main里,创建了二个线程,分别调用方法t1与t2,再加上主线程本身,一并有三个线程,运行后,三个线程都在计数输出,结果类似如下:

t2的x:1
t1的x:1
主线程中的x:1
t2的x:2
t1的x:2
主线程中的x:2
t2的x:3
t1的x:3
主线程中的x:3
t2的x:4
t1的x:4
主线程中的x:4
t2的x:5
t1的x:5
主线程中的x:5

 

三个线程的顺序,在这段代码中我们是无法控制的,天知道谁先开始/谁先结束,反正都是"并行"处理,完全看CPU当时的心情  :)

问题:如果需求有变化,比如要求在主线程执行到某个特定的位置(或时间点)时,才让其它线程开始介入,该怎么做呢?(这种情况实际中很常见,比如某一项计算的入口参数依赖于另一项计算的结果,再比如我们计算月工资前,得先统计出员工当月考勤情况)

System.Threading命名空间下有一个ManualResetEvent类,可以做到这一点:

using  System;
using  System.Threading;

namespace  ManualResetEventStudy
{

    
class  ThreadClass
    {       

        
static  ManualResetEvent mre  =   new  ManualResetEvent( false );

        
static   void  t1()
        {
            
mre.WaitOne( 1000 ); // 等待1秒后,自行启动
             for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t1的x: "   +  x);
            }
        }

        
static   void  t2()
        {
            
mre.WaitOne(); // 一直等待下去,直到有"人"调用mre.set()发出信号为止
             for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" t2的x: "   +  x);
            }
        }

        
static   void  Main( string [] args)
        {
            Thread thrd1 
=   new  Thread(t1);
            thrd1.Start();

            Thread thrd2 
=   new  Thread(t2);
            thrd2.Start();


            
for  ( int  x  =   1 ; x  <=   5 ; x ++ )
            {
                Thread.Sleep(
500 );
                Console.WriteLine(
" 主线程中的x: "   +  x);

                 if  (x  ==   3
                {
                    mre.Set(); // 通知所有等待的线程:“同志们,可以动啦”:)
                }
            }

            Console.Read();
        }        

    }
}

 t1方法中,我们用 mre.WaitOne(1000);让调用该方法的线程先等候1秒,t2方法中,我们用mre.WaitOne()无限等候,然后主线程中计数到3的时候,手动调用mre.Set()方法唤醒所有等候中的线程,运行结果类似下面这样:

主线程中的x:1
主线程中的x:2
t1的x:1
主线程中的x:3
t1的x:2
t2的x:1
主线程中的x:4
t1的x:3
主线程中的x:5
t2的x:2
t1的x:4
t2的x:3
t1的x:5
t2的x:4
t2的x:5

 

 

 

目录
相关文章
|
4月前
|
C#
C# | 使用AutoResetEvent和ManualResetEvent进行线程同步和通信
在多线程编程中,AutoResetEvent 和 ManualResetEvent 是两个常用的同步原语。它们用于线程间的通信和协调,以确保线程按照特定的顺序执行。本篇博客将介绍这两种同步原语的概念、用法和区别。
83 0
C# | 使用AutoResetEvent和ManualResetEvent进行线程同步和通信
C# 使用ManualResetEvent 进行线程同步
上一篇我们介绍了AutoResetEvent,这一篇我们来看下ManualResetEvent ,顾名思义ManualResetEvent  为手动重置事件。 AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别。
828 0
C#多线程之二:ManualResetEvent和AutoResetEvent
转自博客:http://www.cnblogs.com/charley_yang/archive/2010/10/31/1865663.html 初次体验 ManualResetEvent和AutoResetEvent主要负责多线程编程中的线程同步;以下一段是引述网上和MSDN的解析: 在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别。
1064 0
|
Windows
重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent
原文:重新想象 Windows 8 Store Apps (47) - 多线程之线程同步: Semaphore, CountdownEvent, Barrier, ManualResetEvent, AutoResetEvent [源码下载] 重新想象 Windows 8 Store Apps (...
697 0
|
22天前
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
46 1
|
5天前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
24 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
7天前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
24 10
|
14天前
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。