如何实现线程池的 QueueUserWorkItem 方法的延续?
咨询区
PedroC88
如果我将 Job 通过 QueueUserWorkItem
方法丢到线程池的话,请问我如何让程序在该 Job 完成后继续执行,我知道可以添加一些逻辑代码来完成此项功能,但我想知道有没有类似 Thread.Join()
或者怎么提取到被赋于 job 的线程 ?
回答区
Alex Aza
你可以使用类似 ManualResetEvent
内核事件去同步,参考下面代码:
private static ManualResetEvent resetEvent = new ManualResetEvent(false);public static void Main()
{ThreadPool.QueueUserWorkItem(arg => DoWork());resetEvent.WaitOne();
}public static void DoWork()
{Thread.Sleep(5000);resetEvent.Set();
}
如果不想把 event 嵌入到 方法中,可以在 QueueUserWorkItem
委托方法中执行,比如下面这样。
var resetEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(arg => {DoWork();resetEvent.Set();});
resetEvent.WaitOne();
对于批量操作,可以定义一个 List<ManualResetEvent>
。
var events = new List<ManualResetEvent>();foreach(var job in jobs)
{ var resetEvent = new ManualResetEvent(false);ThreadPool.QueueUserWorkItem(arg =>{DoWork(job);resetEvent.Set();});events.Add(resetEvent);
}
WaitHandle.WaitAll(events.ToArray());
Brian Gideon
可以用 CountdownEvent
或者 Barrier
来做同步。
Barrier barrier = new Barrier(3);
for(int i = 0; i < 2; i++)
{ThreadPool.QueueUserWorkItem((state) =>{foo();barrier.SignalAndWait();}, null);
}
barrier.SignalAndWait();/* 或者*/using (var finished = new CountdownEvent(1))
{foreach (var workitem in workitems){var capture = workitem; // Used to capture the loop variable in the lambda expression.finished.AddCount(); // Indicate that there is another work item.ThreadPool.QueueUserWorkItem((state) =>{try{ProcessWorkItem(capture);}finally{finished.Signal(); // Signal that the work item is complete.}}, null);}finished.Signal(); // Signal that queueing is complete.finished.Wait(); // Wait for all work items to complete.
}
点评区
如果一定要在 QueueUserWorkItem
中拦截,最好的方式还是用各种锁比较好,如果在实际开发中,建议还是用 Task
,它具有强大的编排能力。
如何实现线程池的 QueueUserWorkItem 方法的延续?相关推荐
- 13.ThreadPoolExecutor线程池之submit方法
jdk1.7.0_79 在上一篇<ThreadPoolExecutor线程池原理及其execute方法>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法 ...
- java中线程池的使用方法
1 引入线程池的原因 由于线程的生命周期中包括创建.就绪.运行.阻塞.销毁阶段,当我们待处理的任务数目较小时,我们可以自己创建几个线程来处理相应的任务,但当有大量的任务时,由于创建.销毁线程需要很大的 ...
- Java Executor源码解析(3)—ThreadPoolExecutor线程池execute核心方法源码【一万字】
基于JDK1.8详细介绍了ThreadPoolExecutor线程池的execute方法源码! 上一篇文章中,我们介绍了:Java Executor源码解析(2)-ThreadPoolExecutor ...
- Java线程池的使用方法
前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...
- 线程池中submit()方法与execute()方法的区别
execute()方法实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提 ...
- java 线程池 固定大小_使用Executors服务在Java中创建固定大小线程池的最佳方法...
查看源代码,您将意识到: Executors.newFixedThreadPool(threadPoolSize); 相当于: return new ThreadPoolExecutor(thread ...
- 线程池ThreadPool,线程池底层ThreadPoolExecutor方法七大参数,拒绝策略,以及实际开发中高并发下用到哪个线程池?
为什么要用线程池 基本的三个线程池的底层就是ThreadPoolExecutor类 ExecutorService threadPool = Executors.newFixedThreadPool( ...
- 为什么线程池里的方法会执行两次_新手一看就懂的线程池
作者:码农田小齐 来源:https://www.cnblogs.com/nycsde/p/14003888.html 那相信大家也能感受到,其实用多线程是很麻烦的,包括线程的创建.销毁和调度等等,而且 ...
- 深入分析3种线程池执行任务的逻辑方法
摘要:结合ThreadPoolExecutor类的源码深度分析线程池执行任务的整体流程. 本文分享自华为云社区<[高并发]通过ThreadPoolExecutor类的源码深度解析线程池执行任务的 ...
最新文章
- R语言apropos函数查找包含特定字符的函数、find函数查找函数所在的位置实战
- 再迎利好,“预共识”或能助力BCH“零确认”安全可靠
- 用Socket 打造跨语言跨操作系统的网络MORPG游戏(二)
- wxWidgets:文件类和函数
- 使用Visio进行UML建模
- 【转载保存】B+树索引原理以及应用案例
- 使用 Python 实现鼠标键盘自动化
- apache 配置虚拟目录
- Uncaught TypeError: l.push is not a function
- (转)SQL Server 数据类型映射
- 十款乐高积木虚拟搭建软件,乐高仿真工具,积木模拟搭建耗材统计评估软件...
- 使用Resource Hacker+W32Dasm+OD移除警告窗口
- IT项目管理之第5章 项目时间管理习题之案例分析汇总
- office二级笔记
- 论文分享Why Do Adversarial Attacks Transfer? Explaining Transferability of Evasion and Poisoning Attacks
- 总有个短信发来一行乱码_总是收到乱码短信
- 帝国cms系统使用初级教程一(较全面)
- 江西丰收节直播带货 国稻种芯·中国水稻节:消费季产销两旺
- 黄金分割法 ( 三分法 )
- python控制手机模拟器_Appium+python自动化之连接模拟器并启动淘宝APP(超详解)...