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都是无状态的. 线程安全体 ...
随机推荐
- Swift概览
<pre name="code" class="objc">转自:http://letsswift.com/2014/06/swift_overvi ...
- iPad 3g版完美实现打电话功能(phoneitipad破解)
看到这个标题,有的同学可能吐槽,iPad 用来打电话,多雷人啊,人家apple设计的时候没加电话功能是有益这样做的. 只是这次真的有这种需求,一台測试用的iPad 1 3G版的机器,放进去了一张3G电 ...
- linux上安装ftp
1.安装 rpm -ivh vsftpd-2.2.2-11.el6_4.1.x86_64.rpm 2.启动 service vsftpd start 3.连接 windows 命令行输入 ftp ww ...
- Oracle database server 安装tips
需要手动解压第二个包的文件合并到第一个包的相同目录中. 以12c为例,需要把 winx64_12102_SE2_database_1of2.zip和winx64_12102_SE2_database_ ...
- Spring任务调度
任务调度是大多数应用系统的常见需求之一,拿论坛来说:每个半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行对锁定过期的用户进行解锁.以上都是以时间为关注点的调度,事实上 ...
- JAVA_JSON_example
package cn.kjxy.JSON; import java.util.List; import org.json.JSONArray; import org.json.JSONExceptio ...
- JAVA_JSON
package cn.kjxy.JSON; import org.json.JSONArray; import org.json.JSONException; import org.json.JSON ...
- 为什么虚拟机上刚装的centos7只有lo回环网络接口?
centos7默认安装时需要手动激活有线网卡.如果安装时没有激活,需要手动编辑vi /etc/sysconfig/network-scripts/下ifcfg-enoxxONBOOT="ye ...
- sharepoint 删除list里的所有内容
[System.reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") $siteUrl = " ...
- 在ASP中限制同一表单被多次提交
本文介绍在ASP应用中防止用户在当前会话期间多次提交同一表单的一个简单方法.它主要由四个子程序组成,在较为简单的应用场合,你只要将这些代码放在包含文件中直接引用即可:对于那些较为复杂的环境,我们在文章 ...