netframework中等待多个子线程执行完毕并计算执行时间
本文主要描述在.netframework中(实验环境.netframework版本为4.6.1)提供两种方式等待多个子线程执行完毕。
- ManualResetEvent
在多线程中,将ManualResetEvent实例作为方法传入,线程执行完毕后可以设置标志位来标识当前线程已经执行完毕。代码如下:
List<ManualResetEvent> manualResetEvents = new List<ManualResetEvent>();
/// <summary>
/// ManualResetEvent标志多线程是否执行完毕
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_ManualResetEvent_Click(object sender, EventArgs e)
{
// SetBtnEnabled(false);
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = ; i < threadCount; i++)
{
ManualResetEvent manualReset = new ManualResetEvent(false);
manualResetEvents.Add(manualReset);
ThreadPool.QueueUserWorkItem(ManualResetEventMethod, manualReset);
}
//等待所有线程执行完毕
WaitHandle.WaitAll(manualResetEvents.ToArray());
//暂停watch,获取多线程执行时间
watch.Stop();
long time = watch.ElapsedMilliseconds;
lab_time.Text = time.ToString(); // SetBtnEnabled(true); //释放句柄
manualResetEvents.Clear();
} private void ManualResetEventMethod(object obj)
{
Thread.Sleep();
ManualResetEvent mre = (ManualResetEvent)obj;
mre.Set();
}
注意:
在WaitHandle.WaitAll方法中,等待的句柄不能超过64,所以每次用完后,需要手动调用Clear方法进行释放。
如果等待的线程超过64个,可以参考博客:https://www.cnblogs.com/xiaofengfeng/archive/2012/12/27/2836183.html,在该博客中,通过对ManualResetEvent的封装,能够使等待的句柄超过64(测试环境下一次起1000个线程,没有问题)
- Monitor
在主线程中通过Monitor.Wait(locker)达到阻塞的目的,子线程执行完毕通过 Monitor.Pulse(locker)通知主线程,直到所有子线程执行完成,主线程再继续执行,代码如下:
object locker = new object();
int threadCount = ;
int finshCount = ;
/// <summary>
/// Monitor线程之间同步标记多线程执行完毕
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Monitor_Click(object sender, EventArgs e)
{
finshCount = ;
SetBtnEnabled(false);
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = ; i < threadCount; i++)
{
Thread trd = new Thread(new ParameterizedThreadStart(MonitorMethod));
trd.Start(i);
}
lock (locker)
{
while (finshCount != threadCount)
{
Monitor.Wait(locker);//等待
}
}
//所有线程执行完毕,获取执行时间
watch.Stop();
long time = watch.ElapsedMilliseconds;
lab_time.Text = time.ToString(); SetBtnEnabled(true);
} private void MonitorMethod(object obj)
{
Thread.Sleep();
lock (locker)
{
finshCount++;
Monitor.Pulse(locker); //完成,通知等待队列,告知已完,执行下一个。
}
}
在一次开启10、1000个线程两种环境下,分别测试以上两种方式,ManualResetEvent在多次执行时,前几次耗时会比较大,后续耗时会减少并且稳定下来,接近 Monitor的速度。相对而言,Monitor的效率更高。
如果了解过go语言,会发现通过sync包下的WaitGroup也可以达到同样的目的,代码如下:
package main import (
"fmt"
"sync"
"time"
) var wg sync.WaitGroup
var count = 1000 func main() { startTime := time.Now().Unix()
wg.Add(count)
for i := 0; i < count; i++ {
go func() {
defer wg.Done()
time.Sleep(time.Second)
}()
}
fmt.Println("waiting for all goroutine")
wg.Wait() endTime := time.Now().Unix() fmt.Printf("all goroutine is done! time:%v s", (endTime-startTime)) }
相较而言,go语言的协程效率最高
netframework中等待多个子线程执行完毕并计算执行时间的更多相关文章
- Java多线程--让主线程等待所有子线程执行完毕
数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis() ...
- java主线程等待所有子线程执行完毕在执行(常见面试题)
java主线程等待所有子线程执行完毕在执行(常见面试题) java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个 ...
- c#等待所有子线程执行完毕方法
当我们在使用线程中,你会发现主线结束后子线程的结果才显示出来.现在我要等待所以子线程结束,然后在显示结果,怎么做呢? 方法如下: 1.使用 ManualResetEvent,代码如下: using ...
- Java主线程等待所有子线程执行完毕再执行解决办法(转)
方法一: Thread.join()方法,亲测可行,thread.join()方法 Vector<Thread> ts = new Vector<Thread>(); for ...
- CountDownLatch用法---等待多个线程执行完才执行
CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 Coun ...
- C# 多线程join的用法,等待多个子线程结束后再执行主线程
等待多个子线程结束后再执行主线程 class MultiThread{ #region join test public void MultiThreadTest() { Thread[] ths = ...
- java并发编程学习:如何等待多个线程执行完成后再继续后续处理(synchronized、join、FutureTask、CyclicBarrier)
多线程应用中,经常会遇到这种场景:后面的处理,依赖前面的N个线程的处理结果,必须等前面的线程执行完毕后,后面的代码才允许执行. 在我不知道CyclicBarrier之前,最容易想到的就是放置一个公用的 ...
- Java主线程在子线程执行完毕后再执行
一.join() Thread中的join()方法就是同步,它使得线程之间由并行执行变为串行执行. public class MyJoinTest { public static void main( ...
- Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行
Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行 Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执 ...
随机推荐
- SQL Server ALwayson 正在解析
原因:把主库切换到辅助副本以后,集群全部出现正在解析的情况,数据库显示“恢复挂起” 过程:把服务器重启,原以为正在解析会恢复正常.结果失败. 解决方法:出现“正在解析”的情况跟故障转移群集有关,进故障 ...
- 初级练手项目——用Python一步一步实现“智能”贪吃蛇!
贪吃蛇作为一款经典的小游戏,想必大家一定并不陌生,今天我们就来用Python来设计与实现贪吃蛇游戏,回味一下童年的快乐.快跟着小编来看看吧! 基本环境配置 ●版本:Python3 ●系统:Wind ...
- POJ:1751-Highways(Kruskal和Prim)
Highways Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6078 Accepted: 1650 Special Judg ...
- Linux学习-Shell的变量功能
什么是变量? 简单的说,就是让某一个特定字串代表不固定的内容. 变量的可变性与方便性 举例来说,我们每个帐号的邮件信箱默认是以 MAIL 这个变量来进行存取的, 当 dmtsai 这个 使用者登陆时, ...
- configurationChanges
在Android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置.在activity加上android:c ...
- RHEL6.X设置163yum源
目录 RHEL6.X设置163yum源 卸载系统的yum 检查是否已经卸载完成 下载yum以及相关包 安装yum相关rpm包 清除原有缓存,建立yum列表 本地yum源设置 挂载本地光盘 修改配置文件 ...
- spark作业
假定用户有某个周末网民网购停留时间的日志文本,基于某些业务要求,要求开发 Spark应用程序实现如下功能: 1.实时统计连续网购时间超过半个小时的女性网民信息. 2.周末两天的日志文件第一列为姓名,第 ...
- MyCAT+MySQL 搭建高可用企业级数据库集群——第3章 MyCat核心配置讲解
3-1 章节综述 3-2 常用配置文件间的关系 3-3 server.xml配置详解 3-4 log4j2.xml配置文件 3-5 rule.xml 3-6 常用分片算法(上) 3-7 常用分片算法( ...
- jQuery 样式操作、文档操作、属性操作的方法总结
文档操作: addClass() 向匹配的元素添加指定的类名.after() 在匹配的元素之后插入内容.append() ...
- 用Navicat Premium快速查看mysql数据库版本信息
在出现的界面输入命令 select version();