C#多线程(二)
一、线程池
每次创建一个线程,都会花费几百微秒级别的时间来创建一个私有的局部栈,每个线程默认使用1M的内存。这个可以在使用Thread类的构造函数时设置:
- new Thread(new ThreadStart(Go), 2);
- new Thread(new ParameterizedThreadStart(Go("hello")), 3);
提供的两种构造函数方式都提供了对应的设置线程局部栈的大小。线程池通过共享和回收线程的方式来分配这些内存,这样可以使多线程运行在一个非常细粒度级别上而不影响性能。这对于充分利用多核处理器,使用分而治之的方式进行密集型计算的程序中很有用。同时线程池维护一个所有同时运行的工作线程总数的上限,如果有过多的活动线程就会加重操作系统的负担,使诸如CPU缓存失效等问题,当达到这个上限后,就要进行排队。这个线程队列使得任意并发的应用成为可能,如Web服务器就是这种原理。
有多种方式进入线程池:
- 通过Task Parallel Library(.NET 4 TPL)
- 通过调用ThreadPool.QueueUserWorkItem
- 通过异步委托方式
- 使用BackgroundWorker
- WCF、Remoting、ASP.NET、ASMX webservice
- System.Timers.Timer和System.Threading.Timer
- .NET中以Async结束命名的方法
- PLINQ
- 不能对放入线程池中的线程命名,这会使得调试更加困难
- 线程池中的线程总是后台线程
- 阻塞线程池中的线程困难引发额外的延迟
- CurrentTread.IsThreadPoolThread
二、进入线程池
- static void Main(string[] args)
- {
- Task.Factory.StartNew(Go);
- Console.WriteLine("Is Thread Pool: " + Thread.CurrentThread.IsThreadPoolThread.ToString());
- Console.ReadKey();
- }
- static void Go()
- {
- Console.Write("Is Thread Pool: " + Thread.CurrentThread.IsThreadPoolThread.ToString());
- }
Task.Factory.StartNew返回一个Task对象可以用来监控这个任务。
- static void Main(string[] args)
- {
- Task<string> task = Task.Factory.StartNew<string>(Go);
- Console.WriteLine("Is Thread Pool: " + Thread.CurrentThread.IsThreadPoolThread.ToString());
- if (task.IsCompleted)
- {
- string result = task.Result;
- Console.WriteLine(task.IsCompleted.ToString() + result);
- }
- Console.ReadKey();
- }
- static string Go()
- {
- return Thread.CurrentThread.IsThreadPoolThread.ToString();
- }
如果在工作线程中出现异常,当获取Task的Result属性时会重新引发AggregateException异常,如果没有查询Result或者没有调用Wait方法,所有未处理的异常都会终止进程执行。
- static void Main()
- {
- ThreadPool.QueueUserWorkItem (Go);
- ThreadPool.QueueUserWorkItem (Go, 123);
- Console.ReadLine();
- }
- static void Go (object data) // data will be null with the first call.
- {
- Console.WriteLine ("Hello from the thread pool! " + data);
- }
- static void Main()
- {
- Func<string, int> method = Work;
- method.BeginInvoke ("test", Done, method);
- // ...
- //
- }
- static int Work (string s) { return s.Length; }
- static void Done (IAsyncResult cookie)
- {
- var target = (Func<string, int>) cookie.AsyncState;
- int result = target.EndInvoke (cookie);
- Console.WriteLine ("String length is: " + result);
- }
三、线程池的优化
- 32位的.NET4.0环境为1023个
- 64位的.NET4.0环境为32768个
- .NET 3.5为每个CPU核 250个
- .NET2.0 为每个CPU核25个
- ThreadPool.SetMinThreads(50,50);
C#多线程(二)的更多相关文章
- java 多线程二
java 多线程一 java 多线程二 java 多线程三 java 多线程四 线程中断: /** * Created by root on 17-9-30. */ public class Test ...
- java基础-多线程二
java基础-多线程二 继承thread和实现Runnable的多线程每次都需要经历创建和销毁的过程,频繁的创建和销毁大大影响效率,线程池的诞生就可以很好的解决这一个问题,线程池可以充分的利用线程进行 ...
- C#夯实基础之多线程二:主线程、前台线程与后台线程
我们在<C#夯实基础之多线程一:初识多线程>一文中第二部分中指出,既然windows最终发展出了多线程模型,按理说,我们直接使用一个.NetFramework的线程类就可以直接撸代码了,但 ...
- Java:多线程<二> 同步
由于多线程的访问出现延迟和线程的随机性,在使用多线程时往往会伴随安全性的问题,这些问题一旦出现将会是非常严重的.为了解决这种安全性问题,synchronized出现了. synchronized用法一 ...
- Java多线程——<二>将任务交给线程,线程声明及启动
一.任务和线程 <thinking in java>中专门有一小节中对线程和任务两个概念进行了具体的区分,这也恰好说明任务和线程是有区别的. 正如前文所提到的,任务只是一段代码,一段要达成 ...
- 从零开始学习Java多线程(二)
前面已经简单介绍进程和线程,为后续学习做铺垫.本文讨论多线程传参,Java多线程异常处理机制. 1. 多线程的参数传递 在传统开发过程中,我们习惯在调用函数时,将所需的参数传入其中,通过函数内部逻辑处 ...
- 多线程二:线程池(ThreadPool)
在上一篇中我们讲解了多线程的一些基本概念,并举了一些例子,在本章中我们将会讲解线程池:ThreadPool. 在开始讲解ThreadPool之前,我们先用下面的例子来回顾一下以前讲过的Thread. ...
- Java多线程(二) —— 深入剖析ThreadLocal
对Java多线程中的ThreadLocal类还不是很了解,所以在此总结一下. 主要参考了http://www.cnblogs.com/dolphin0520/p/3920407.html 中的文章. ...
- python多线程(二)
原文:http://blog.sina.com.cn/s/blog_4b5039210100esc1.html 基础不必多讲,还是直接进入python. Python代码代码的执行由python虚拟机 ...
- 并发和多线程(二)--线程安全、synchronized、CAS简介
线程安全性: 当多个线程访问一个类的时候,这个类始终表示出正确的行为,那么这个类是线程安全的. 无状态的对象一定是线程安全的,例如大部分service.dao.Servlet都是无状态的. 线程安全体 ...
随机推荐
- Windows 8.1 Hyper-V安装的虚拟机
一.安装Hyper-v Hyper-V内置于Windows 8中,用户无需格外的下载安装文件,只需要到Windows 8的程序管理中将其选中开启功能即可. 具体步骤:控制面板→程序→启用或关闭Wind ...
- JForum 2.19源码部署到eclipse
前两天在研究免费论坛,通过oschina和相关的文档查阅,最终选择了jforum,首先他是java写的,其次方便二次开发,而且有些论坛的源码都已经不在维护了,jforum最近几个月还是有更新的,但是从 ...
- windows下mysql初始密码设置
转载自:http://blog.csdn.net/ofreelander/article/details/50802780 1.my-default.ini 改名my.ini 在解压的目录下面复制my ...
- MySQL提供的错误日志中的错误级别一共有3个分别为:
ERROR_LEVEL-->错误级别 WARNING_LEVEL-->警告级别 INFORMATION_LEVEL-->信息级别
- nginx 安装部署
1. 安装passenger:sudo gem install passenger 2. 找到passenger的安装目录,一般是 cd /var/lib/gems/2.0.0/gems/passe ...
- JFace中的表格型树TableTreeViewer
表格型树是用TableTreeViewer来实现,自从SWT下的TableTree被废弃之后,其扩展TableTreeViewer也成了鸡肋,不再被建议使用,既然Tree可以实现表格型树,那么其扩展T ...
- Time complexity analysis of algorithms
时间复杂性的计算一般而言,较小的问题所需要的运行时间通常要比较大的问题所需要的时间少.设一个程序P所占用的时间为T,则 T(P)=编译时间+运行时间. 编译时间与实例特征是无关的,且可假设一个编译过的 ...
- #284 div.2 C.Crazy Town
C. Crazy Town Crazy Town is a plane on which there are n infinite line roads. Each road is defined ...
- Leetcode 104. Maximum Depth of Binary Tree(二叉树的最大深度)
Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...
- 20160503-spring入门1
一.Spring是什么 Spring是一个开源的控制反转(Inversion of Control ,IoC)和面向切面(AOP)的容器框架.它的主要目得是简化企业开发. IOC 控制反转 publ ...