线程池同步问题

问题描述

intnum=10;ManualResetEvent[]ms=newManualResetEvent[num];for(inti=0;i<num;i++){ms[i]=newManualResetEvent(false);}for(inti=0;i<num;i++){ThreadPool.QueueUserWorkItem(delegate(objectobj){intindex=Convert.ToInt32(obj);Thread.Sleep(5000);ms[index].Set();},i);}WaitHandle.WaitAll(ms);MessageBox.Show("运行结束");如果线程池中的线程是并发运行的话,那么应该就是在5秒钟后运行结束,但是实际不是这样

解决方案

解决方案二:
这个很正常,线程池启动需要一点点时间,更何况,线程池的数量是.net控制的,不会一下帮你开10个的,所以不会再5s的时候结束。
解决方案三:
那用了多长时间?
解决方案四:
退一步讲,就算Net给你创建了10个独立线程执行(正常应该不会),你的CPU有10核去同时执行这10个线程吗?没有的话,还不是CPU给你分配时间片,一个线程执行一会,5秒肯定不会结束
解决方案五:
引用3楼wjkaola123的回复:

退一步讲,就算Net给你创建了10个独立线程执行(正常应该不会),你的CPU有10核去同时执行这10个线程吗?没有的话,还不是CPU给你分配时间片,一个线程执行一会,5秒肯定不会结束

说的到位了我在代码上加了时间显示,你看下就明白了intnum=10;ManualResetEvent[]ms=newManualResetEvent[num];Console.WriteLine("{0,-15}--------START--------",DateTime.Now);for(inti=0;i<num;i++){ms[i]=newManualResetEvent(false);}for(inti=0;i<num;i++){ThreadPool.QueueUserWorkItem(delegate(objectobj){intindex=Convert.ToInt32(obj);Console.WriteLine("{0,-15}{1}SLEEP",DateTime.Now,index);Thread.Sleep(5000);Console.WriteLine("{0,-15}{1}AWAKE",DateTime.Now,index);ms[index].Set();},i);}WaitHandle.WaitAll(ms);Console.WriteLine("{0,-15}--------STOP--------",DateTime.Now);

解决方案六:
引用4楼qqamoon的回复:

说的到位了我在代码上加了时间显示,你看下就明白了

不用考虑时间显示。你可以在你的第一个出现的“AWAKE”之前数一下一共出现了多少个"SLEEP”,就知道当前系统线程池中有多少你所注册任务在“并发”执行。另外,你把Thread.Sleep(5000)再改为Thread.Sleep(8000)看看线程池又给你分配了多少并发数量。
解决方案七:
线程池中会并发执行你的全部10个任务,这没有问题,这跟CPU核心数没有关系。但是线程池会延迟启动任务,而不会一股脑地将所有任务同时启动。这是优化性能的手段。
解决方案八:
哦,我还以为#4楼是lz的自己的跟帖。要看“并发数”,不要绕道“时间”去看,那样反而不容易数清楚并发数。应该设计一个int变量来统计。

时间: 2024-11-03 21:32:40

线程池同步问题的相关文章

线程池-多线程同步数据且等多线程同时完成后再走主线程

问题描述 多线程同步数据且等多线程同时完成后再走主线程 用线程池管理,开10条线程去读取和更新几十万数据,但是主线程直接跑下去了,这个不能允许,但是线程池又不能用join来.自己建Thread join,这10条线程又是一条条运行,不合要求.应该如何做,谢谢 解决方案 子进程睡眠不同的时间,父进程wait但是忽略子进程死信号,这样父进程会是最后退出的

linux C 多线程/线程池编程 同步实例

在多线程.线程池编程中经常会遇到同步的问题. 1.创建线程 函数原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg); 参数:thread指向线程id的指针:attr指向线程属性的指针:第三个为执行的方法的函数指针:arg指向给方法传递的参数的指针. 2.互斥变量 (1)互斥变量  pthread_mutex_t (2)互斥变量

100行Java代码构建一个线程池

在现代的操作系统中,有一个很重要的概念――线程,几乎所有目前流行的操作系统都支持线程,线程来源于操作系统中进程的概念,进程有自己的虚拟地址空间以及正文段.数据段及堆栈,而且各自占有不同的系统资源(例如文件.环境变量等等).与此不同,线程不能单独存在,它依附于进程,只能由进程派生.如果一个进程派生出了两个线程,那这两个线程共享此进程的全局变量和代码段,但每个线程各拥有各自的堆栈,因此它们拥有各自的局部变量,线程在UNIX系统中还被进一步分为用户级线程(由进程自已来管理)和系统级线程(由操作系统的调

浅谈.NET下的多线程和并行计算(六)线程池基础 下

这节我们按照线程池的核心思想来自定义一个简单的线程池: 1) 池中使用的线程不少于一定数量,不多于一定数量 2) 池中线程不够的时候创建,富裕的时候收回 3) 任务排队,没有可用线程时,任务等待 我们的目的只是实现这些"需求",不去考虑性能(比如等待一段时间再去创建新的线程等策略)以 及特殊的处理(异常),在实现这个需求的过程中我们也回顾了线程以及线程同步的基本概念. 首先,把任务委托和任务需要的状态数据封装一个对象: public class WorkItem { public Wa

线程池的介绍及简单实现

服务器程序利用线程技术响应客户请求已经司空见惯,可能您认为这样做效率已经很高,但您有没有想过优化一下使用线程的方法.该文章将向您介绍服务器程序如何利用线程池来优化性能并提供一个简单的线程池实现. 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收.所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利

戏(细)说Executor框架线程池任务执行全过程(下)

原文链接:   首发表于infoq.com 2015年6月 上一篇文章中通过引入的一个例子介绍了在Executor框架下,提交一个任务的过程,这个过程就像我们老大的老大要找个老大来执行一个任务那样简单.并通过剖析ExecutorService的一种经典实现ThreadPoolExecutor来分析接收任务的主要逻辑,发现ThreadPoolExecutor的工作思路和我们带项目的老大的工作思路完全一致.在本文中我们将继续后面的步骤,着重描述下任务执行的过程和任务执行结果获取的过程.会很容易发现,

Java线程池的理论与实践

前段时间公司里有个项目需要进行重构,目标是提高吞吐量和可用性,在这个过程中对原有的线程模型和处理逻辑进行了修改,发现有很多基础的多线程的知识已经模糊不清,如底层线程的运行情况.现有的线程池的策略和逻辑.池中线程的健康状况的监控等,这次重新回顾了一下,其中涉及大量java.util.concurrent包中的类.本文将会包含以下内容: Java中的Thread与操作系统中的线程的关系 线程切换的各种开销 ThreadGroup存在的意义 使用线程池减少线程开销 Executor的概念 Thread

[并发]线程池技术小白

1  线程池技术介绍 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收.所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因.比如大家所熟悉的数据库连接池正是遵循这一思想而产生的,本文将介绍的线程池技术同样符合这一思想.

NGINX引入线程池 性能提升9倍

1. 引言 正如我们所知,NGINX采用了异步.事件驱动的方法来处理连接.这种处理方式无需(像使用传统架构的服务器一样)为每个请求创建额外的专用进程或者线程,而是在一个工作进程中处理多个连接和请求.为此,NGINX工作在非阻塞的socket模式下,并使用了epoll 和 kqueue这样有效的方法. 因为满负载进程的数量很少(通常每核CPU只有一个)而且恒定,所以任务切换只消耗很少的内存,而且不会浪费CPU周期.通过NGINX本身的实例,这种方法的优点已经为众人所知.NGINX可以非常好地处理百