C#(ThreadPool)线程池的详解及使用范例

此文章是根据乌班图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());
    }
}

 

  • 10
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是引用中的代码示例: ```java ExecutorService executor = Executors.newFixedThreadPool(2); Runnable worker = new Runnable() { public void run() { // do some work } }; executor.execute(worker); ``` 这段代码创建了一个固定大小的线程池,其中corePoolSize为2,maximumPoolSize也为2。这意味着线程池最多会保持2个线程处于活动状态,并在任务到达时创建新的线程来处理任务。当队列中没有任务时,线程池中的线程会进入空闲状态,直到有新的任务到来。如果使用的是无界队列(例如LinkedBlockingQueue),那么线程数就不会超过corePoolSize。keepAliveTime参数指定了线程池中的空闲线程在等待新任务时的存活时间。 以下是引用中的代码示例: ```java ExecutorService executor = Executors.newFixedThreadPool(5); Runnable worker = new Runnable() { public void run() { // do some work } }; executor.execute(worker); ``` 这段代码创建了一个固定大小的线程池,其中corePoolSize为5,maximumPoolSize也为5。这意味着线程池最多会保持5个线程处于活动状态,并在任务到达时创建新的线程来处理任务。当队列中没有任务时,线程池中的线程会进入空闲状态,直到有新的任务到来。如果使用的是无界队列(例如LinkedBlockingQueue),那么线程数就不会超过corePoolSize。keepAliveTime参数指定了线程池中的空闲线程在等待新任务时的存活时间。这段代码创建了一个5个线程线程池,如果需要创建更多的线程,可以调整corePoolSize和maximumPoolSize的值。如果使用的是有界队列(例如ArrayBlockingQueue),那么可以通过调用put()方法将任务放入队列中。这段代码展示了如何创建一个固定大小的线程池,并使用execute()方法执行任务。如果需要停止线程池,可以使用shutdown()方法或者shutdownNow()方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [线程池ThreadPool详解](https://blog.csdn.net/qq_43651945/article/details/124717896)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值