栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

多线程之线程池ThreadPool

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程之线程池ThreadPool

一、为什么会有线程池

    前面文章已经介绍了如何使用线程,当每新建一个线程都需要占用内存空间和其他资源,销毁回收线程也需要资源,这对频繁使用线程是不友好的,于是便出现了线程池,线程池中会根据设定挂起几个线程,它们不会自动消除,始终存在,当需要线程时,直接使用线程池中的线程,使用结束后也不会销毁,这样就节约了很多资源。

二、ThreadPool使用介绍 1 使用线程池ThreadPool启用线程

   方法: QueueUserWorkItem(WaitCallback callBack, object state),callBack为执行的方法,state对象对可选参数。

static void Main(string[] args)
{
	Console.WriteLine($"********************* 系统开始 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
	ThreadPool.QueueUserWorkItem(obj =>
	{
		Calculate("Test");
		Console.WriteLine(obj);
	}, "State");
	Console.WriteLine($"********************* 系统结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");
}

static void Calculate(string name)
{
    Console.WriteLine($"********************* 线程-{name}开始 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} ***************");
    long num = 0;
    for (int i = 0; i < 10000000; i++)
    {
        num += i;
    }
    //等待2s
    Thread.Sleep(2000);
    Console.WriteLine($"********************* 线程-{name}结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} ***************");
}

2 其他常用方法
方法名描述
GetMaxThreads获取线程池中辅助线程的最大数目和异步 I/O 线程的最大数目
GetMinThreads获取线程池中辅助线程的最小数目和异步 I/O 线程的最小数目
SetMaxThreads设置线程池最大线程数和最大空闲异步 I/O 线程数
SetMinThreads设置线程池最小线程数和最小空闲异步 I/O 线程数
	int workerMaxThreads;
	int completionPortMaxThreads;
	ThreadPool.GetMaxThreads(out workerMaxThreads, out completionPortMaxThreads);
	Console.WriteLine($"线程池中辅助线程的最大数目:{workerMaxThreads}; 线程池中异步 I/O 线程的最大数目:{completionPortMaxThreads}");
	
	int workerMinThreads;
	int completionPortMinThreads;
	ThreadPool.GetMinThreads(out workerMinThreads, out completionPortMinThreads);
	Console.WriteLine($"线程池中辅助线程的最小数目:{workerMinThreads}; 线程池中异步 I/O 线程的最小数目:{completionPortMinThreads}");
	
	//最小线程数和最小空闲异步 I/O 线程数
	ThreadPool.SetMinThreads(4, 4);
	
	//最大线程数和最大空闲异步 I/O 线程数
	ThreadPool.SetMaxThreads(6, 6);
	
	ThreadPool.GetMaxThreads(out workerMaxThreads, out completionPortMaxThreads);
	Console.WriteLine($"线程池中辅助线程的最大数目:{workerMaxThreads}; 线程池中异步 I/O 线程的最大数目:{completionPortMaxThreads}");
	
	ThreadPool.GetMinThreads(out workerMinThreads, out completionPortMinThreads);
	Console.WriteLine($"线程池中辅助线程的最小数目:{workerMinThreads}; 线程池中异步 I/O 线程的最小数目:{completionPortMinThreads}");


    搞这么多方法,怎么用呢?

static void Main(string[] args)
{
	int workerMaxThreads;
	int completionPortMaxThreads;
	int workerMinThreads;
	int completionPortMinThreads;
	
	//最大线程数和最大空闲异步 I/O 线程数
	ThreadPool.SetMaxThreads(6, 6);
	ThreadPool.GetMaxThreads(out workerMaxThreads, out completionPortMaxThreads);
	Console.WriteLine($"线程池中辅助线程的最大数目:{workerMaxThreads}; 线程池中异步 I/O 线程的最大数目:{completionPortMaxThreads}");
	
	ThreadPool.GetMinThreads(out workerMinThreads, out completionPortMinThreads);
	Console.WriteLine($"线程池中辅助线程的最小数目:{workerMinThreads}; 线程池中异步 I/O 线程的最小数目:{completionPortMinThreads}");
	
	//启用8个线程,但线程池最多只能同时存在6个
	for (int i = 0; i < 8; i++)
	{
	    int k = i + 1;
	    ThreadPool.QueueUserWorkItem(obj =>
	    {
	        Calculate("Test" + k);
	    });
	}
	Console.WriteLine($"********************* 系统结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH: mm:ss.fff")} ***************");

}

static void Calculate(string name)
{
    Console.WriteLine($"********************* 线程-{name}开始 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} ***************");
    long num = 0;
    for (int i = 0; i < 10000000; i++)
    {
        num += i;
    }
    //等待2s
    Thread.Sleep(2000);
    Console.WriteLine($"********************* 线程-{name}结束 线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}  {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} ***************");
}

    这里我们启用了8个线程,但是线程池设置了最多只能同时允许6个线程允许,所以只能等前6个线程最先运行完的2个空出资源第7,8个方法才可以执行。这样看线程池是不是更友好,当你同时启用100个甚至更多个线程(我没试过哦),可能一下电脑卡死,站点挂掉啥的,但有了线程池就不用怕了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/910788.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号