此文章是根据乌班图ysm的博客修改的,并加入了自己的一些见解
线程和线程池都是进行多线程操作的,线程池是用来保存线程的一个容器,在程序创建线程来执行任务的时候线程池才会初始化一个线程,线程在执行完毕之后并不会被销毁,而是被挂起等待下一个任务的到来被激活执行任务,当线程池里的线程不够用的时候会新实例化一个线程,来执行,线程池里的线程会被反复利用。
这和我们打客服电话是一个相似的场景,每个打电话的人是一个任务,每个话务员就像一个线程,话务员处理完一个任务之后并不会被辞退,而是等待下一个任务的到来。如果使用线程来处理问题,就相当于话务员处理完一个任务之后就被辞退了,新任务来的时候就再招聘一个。招聘话务员是要耗费资源的。大概就是这个意思。
范例1:获取线程池的相关信息与线程池运行范例
//存放要计算的数值的字段
public static double num1=-1;
public static double num2=-1;
static void Main(string[] args)
{
//获取线程池的最大的线程数和维护的最小线程数
int maxThreadNum,portThreadNum,minThreadNum;
ThreadPool.GetMaxThreads(out maxThreadNum,out portThreadNum);
ThreadPool.GetMinThreads(out minThreadNum,out portThreadNum);
Console.WriteLine("最大线程数:{0}",maxThreadNum);
Console.WriteLine("最小空闲线程数:{0}",minThreadNum);
//函数变量值
int x=15600;
//启动第一个任务:计算x的8次方
Console.WriteLine("启动第一个任务:计算{0}的8次方.",x);
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1),x);
//启动第二个任务
Console.WriteLine("启动第二个任务:计算{0}的8次方",x);
ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc2),x);
//等待,直到两个数值等完成计算
while(num1==-1||num2==-1);
//打印计算结果
Console.WriteLine("y({0})={1}",x,num1+num2);
}
private void TaskProc2(object state)
{
num1=Math.Pow(Convert.ToDouble(state),8);
}
private void TaskProc1(object state)
{
num2=Math.Pow(Convert.ToDouble(state),8);
}
2.退出线程池的执行
static void Main(string[] args)
{
CancellationTokenSource cts=new CancellationTokenSource();
ThreadPool.QueueUserWorkItem(t=>Counts(cts.Token,1000));
Console.WriteLine("Press Any Key to cancel the operation");
Console.ReadLine();
cts.Cancel();
Console.ReadLine();
}
private void Counts(CancellationToken token,int CountTo)
{
for(int count=0;count<CountTo;count++)
{
if(token.IsCancellationRequested)
{
Console.WriteLine("Count is cancelled");
break;
}
Console.WriteLine(count);
Thread.Sleep(200);
}
Console.WriteLine("Count is stopped");
}
3.比较线程池和线程的执行效率
static void Main(string[] args)
{
Stopwatch sw=new Stopwatch();
sw.Start();
for(int i=0;i<1000;i++)
{
Thread th=new Thread(()=>
{
int count=0;
count++;
});
th.Start();
}
sw.Stop();
Console.WriteLine("运行创建线程所需要的时间"+sw.ElapsedMilliseconds);
sw.Restart();
for(int i=0;i<1000;i++)
{
ThreadPool.QueueUserWorkItem(t=>
{
int count=0;
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
count++;
})
}
sw.Stop();
Console.WriteLine("运行线程池所需要花费的时间:"+sw.ElapsedMilliseconds);
}
4.线程池参数传递执行
static void Main(stirng[] args)
{
//实例化类的对象
ThreadDemoClass demoClass=new ThreadDemoClass();
//WaitCallBack:是一个委托类型,表示要执行的方法
//使用委托绑定线程池要执行的方法(无参数)
WaitCallback wc1=demoClass.Run1;
//将方法排入队列,在线程池变为可用时执行
ThreadPool.QueueUserWorkItem(wc1);
//使用委托绑定线程要执行的方法(带参数)
WaitCallback wc2=new WaitCallback(demoClass.Run1);
//将方法排入队列,在线程池变为可用执行
ThreadPool.QueueUserWorkItem(wc2,"cdc");
UserInfor userInfor=new UserInfor();
userInfor.Name="cdc";
userInfor.Age=36;
//使用委托绑定线程池要执行的方法(有参数,自定义类型的参数)
WaitCallback wc3=new WaitCallback(demoClass.Run2);
//将方法排入队列,在线程池变为可用时执行
ThreadPool.QueueUserWorkItem(wc3,userInfor);
Console.WriteLine();
Console.WriteLine("Main thread working...");
Console.WriteLine("Main thread ID is:"+Thread.CurrentThread.ManagedThreadId);
}
internal calss UserInfor
{
public Age{get;internal set;}
public string{get;internal set;}
}
internal calss ThreadDemoClass
{
public void Run1(object obj)
{
string name=obj as string;
Console.WriteLine("Child thread working...");
Console.WriteLine("My name is "+name);
Console.WriteLine("Child thread ID is:"+Thread.CurrentThread.ManagedThreadId);
}
public void Run2(object obj)
{
UserInfor userInfor=(UserInfor)obj;
Console.WriteLine("Child thread working...");
Console.WriteLine("My name is "+userInfor.Name+",my age"+userInfor.Age);
Console.WriteLine("Child thread ID is: "+Thread.CurrentThread.ManagedThreadId.ToString());
}
}