C# ThreadPool线程池的使用

一.设置线程池的最大最先线程数量

ThreadPool.SetMaxThreads(16,16);// 设置线程池最大线程数量
ThreadPool.SetMinThreads(8, 8);
ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);// 获取线程池最大线程数量
ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);

二.简单使用线程池

// 将线程丢进线程池,参数是线程要做的事情 
ThreadPool.QueueUserWorkItem(t =>
{
     DoSomething("threadPool");
});

三.使用ManualResetEvent做到做到线程池的线程等待

ManualResetEvent manualResetEvent = new ManualResetEvent(false);// false代表线程会阻塞
ThreadPool.QueueUserWorkItem(t =>
{
    DoSomething("threadPool");
    // 等到这个线程完成这件事情后,就设置manualResetEvent变为true
    manualResetEvent.Set();// Set过后(manualResetEvent 变为true),WaitOne就会过去了
    // manualResetEvent.Reset();
});
manualResetEvent.WaitOne();// 只要没有Set回去,线程会一直卡在这里
// 一般来说不要阻塞线程池的线程,因为程序在运行过程中会出现一些问题(死锁问题)
// 如果非要使用那么一定要set回去

四.使用ManualResetEvent出现死锁的情况

// 问题就是在k等于18的时候线程会死锁
for (int i = 0; i < 20; i++)
{
    int k = i;
    ThreadPool.QueueUserWorkItem(t =>
    {
        Console.WriteLine(k);
        if (k < 18)
        {
 // 因为我设置最大线程数只有16个,线程池里面的线程到达16个后就不会往后走了(此时线程都在使用中),就不会到达Set方法,所以就会死锁
 manualResetEvent.WaitOne();// 等待
        }
        else
        {
 manualResetEvent.Set();// 恢复正常的代码
        }
    });
}
if (manualResetEvent.WaitOne())
{
    Console.WriteLine("没有死锁");
}

// 正常的执行是肯定先执行下面这一句
Console.WriteLine("等着QueueUserWorkItem完成后才执行");

五.线程池回调(不带返回值)

private void ThreadPoolWithCallback(Action act, Action callback) {
	ThreadPool.QueueUserWorkItem( t => {
    	act.Invoke();
    	Thread.Sleep(2000);
    	callback.Invoke();
	});
} 

// 使用的时候
// 没有返回参数
ThreadWithCallback(() =>
{
    Console.WriteLine("这里是Action:" + Thread.CurrentThread.ManagedThreadId.ToString());
}, () =>
{
    Console.WriteLine("这里是CallBack:" + Thread.CurrentThread.ManagedThreadId.ToString());
});

六.线程回调(带返回值)

private Func<T> ThreadWithReturn<T>(Func<T> func) {
T t = default(T);
Thread thread = new Thread(() =>
{
     t = func.Invoke();
});
thread.Start();

// 返回一个委托函数
// 委托函数里面还有一个return,这是属于另一个函数了
// 在返回这个Func的时候是不会卡界面的
return () =>
{
    while (thread.ThreadState != ThreadState.Stopped)
    {
        Console.WriteLine("我的");
        Thread.Sleep(2000);
    }
    // 也可以
    //thread.Join();// 表示线程执行到这里后就等待
    return t;
};
       }

// 使用的时候
Func<int> func = ThreadWithReturn<int>(() => {
    Thread.Sleep(2000);
    return DateTime.Now.Millisecond;
});

七.线程池的优点

1)降低资源消耗,尽最大可能的避免线程的创建和销毁带来的性能开销。

2)  提高响应速度,当任务来时可以直接使用,不用等待线程创建(在线程池的线程未被全部占用的时候,可以直接进行运算)

3)避免大量的线程间因互相抢占系统资源导致的阻塞现象。(线程池会自动管理线程)

4}提高线程的可管理性。(线程池会自动管理线程)

—— 完 ——
相关推荐
评论

立 为 非 似

中 谁 昨 此

宵 风 夜 星

。 露 , 辰

文章点击榜

细 无 轻 自

如 边 似 在

愁 丝 梦 飞

。 雨 , 花