c#自己实现线程池功能(二)

介绍

在上一篇c#自己实现线程池功能(一)中,我们基本实现了一个可以运行的程序,而不能真正的称作线程池。由于是上篇中的代码有个致命的bug那就是没有任务是并不是等待,而是疯狂的进行while循环,并试图lock任务链表,这样带来的问题的就是性能相当低下,程序反映速度很慢(当加入一个新任务后,要过很久这个job才开始运行)造成的原因就是刚才所说的。

为了解决这个问题我们就需要使用某种方法使得程序能够让进程同步。

方法一

使用信号量

我们为了减少对task任务的加锁操作,只有当task不为空时才进行试探。我们的信号量就代表的是任务表里面的数量,当s.WaitOne();成功后我们才开始加锁,并取出任务

while (flag && TaskQueue != null)
            {
                //等待任务
                ThreadPoolManager.s.WaitOne();
                //获取任务
                lock (TaskQueue)
                {
                    try
                    {
                        if (TaskQueue.Count > 0)
                            task = TaskQueue.Dequeue();
                        else
                            task = null;
                    }
                    catch (Exception)
                    {
                        task = null;
                    }
                    if (task == null)
                        continue;
                }

在ThreadPoolManager类中加入两个变量

//由于采用信号量需要定义一个
        public int MaxJobNum = 1000;
        public static Semaphore s;

并在初始化这个类时 初始化信号量 s = new Semaphore(0, MaxJobNum);

这样就能够实现同步

下面给出一个测试类

 static void Main(string[] args)
        {
            ThreadPoolManager tpm = new ThreadPoolManager(2);

            TestTask t1 = new TestTask("task1");
            TestTask t2 = new TestTask("task2");
            TestTask t3 = new TestTask("task3");
            TestTask t4 = new TestTask("task4");
            TestTask t5 = new TestTask("task5");
            TestTask t6 = new TestTask("task6");
            TestTask t7 = new TestTask("task7");
            TestTask t8 = new TestTask("task8");
            TestTask t9 = new TestTask("task9");

            tpm.AddTask(t1);
            tpm.AddTask(t2);
            tpm.AddTask(t3);
            tpm.AddTask(t4);
            tpm.AddTask(t5);
            tpm.AddTask(t6);
            tpm.AddTask(t7);
            tpm.AddTask(t8);
            tpm.AddTask(t9);
        }

方法二

我们不是用信号量,我们使用AutoResetEvent来实现同步

第一步,在ThreadPoolManager初始化时候创建一个  locks = new AutoResetEvent(false);

当AddTask的时候locks.Set();通知等待的操作。

然后我们对WorkThread的run函数做一个小小的修改

 public void run()
        {
            while (flag && TaskQueue != null)
            {
                //等待任务
                //ThreadPoolManager.sep.WaitOne();

                //等待任务
                while (TaskQueue.Count == 0 && flag)
                {
                    try
                    {
                        ThreadPoolManager.locks.WaitOne();
                    }
                    catch (Exception)
                    {
                    }
                }
                //获取任务
                lock (TaskQueue)
                {
                    try
                    {
                        task = TaskQueue.Dequeue();
                    }
                    catch (Exception)
                    {
                        task = null;
                    }
                    if (task == null)
                        continue;
                }
                try
                {
                    task.SetEnd(false);
                    task.StartTask();
                }
                catch (Exception)
                {
                }
                try
                {
                    if (!task.IsEnd())
                    {
                        task.SetEnd(false);
                        task.EndTask();
                    }
                }
                catch (Exception)
                {
                }

            }//end of while
        }

只有当task列表的数量为0时我们才阻塞,直到AddTask的时候才继续下去

时间: 2024-10-27 13:14:58

c#自己实现线程池功能(二)的相关文章

Java多线程系列--“JUC线程池”03之 线程池原理(二)

线程池示例 在分析线程池之前,先看一个简单的线程池示例. import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; public class ThreadPoolDemo1 { public static void main(String[] args) { // 创建一个可重用固定线程数的线程池 ExecutorService pool = Executors.newFixedThre

线程池系列二:ThreadPoolExecutor讲解

一.简介 1)线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) 参数讲解:corePoolSize: 线程池维护线

Android线程管理之ExecutorService线程池(二)

前言: 上篇学习了线程Thread的使用,今天来学习一下线程池ExecutorService. 为什么要引入线程池? 1.)new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪. 不利于扩展,比如如定时执行.定期执行.线程中断 2.)采用线程池的优点 重用存在的线程,减少对象创建.消亡的开销,性能佳 可有效控制最大并发线程数,提高系统资源的使用率,同

线程池(二)

1.线程池简介:    多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间. 如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能.                一个线程池包括以下四个基本组成部分:                1.线程池管理器(ThreadPool):用于创建并管理线程池,包

MySQL具体解释(8)----------MySQL线程池总结(二)

这篇文章是对上篇文章的一个补充,主要环绕下面两点展开.one-connection-per-thread的实现方式以及线程池中epoll的使用. one-connection-per-thread 依据scheduler_functions的模板,我们也能够列出one-connection-per-thread方式的几个关键函数. static scheduler_functions con_per_functions= { max_connection+1, // max_threads NU

MySQL详解(8)----------MySQL线程池总结(二)

这篇文章是对上篇文章的一个补充,主要围绕以下两点展开,one-connection-per-thread的实现方式以及线程池中epoll的使用. one-connection-per-thread 根据scheduler_functions的模板,我们也可以列出one-connection-per-thread方式的几个关键函数. static scheduler_functions con_per_functions= { max_connection+1, // max_threads NU

c#自己实现线程池功能(一)

线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源,所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因.比如大家所熟悉的数据库连接池正是遵循这一思想而产生的,本文将介绍的线程池技术同样符合这一思想. 线程池技术如何提高服务器程序的性能 我所提到服务器程序是指能够接受客户请求并能处理请求的

线程池总结(二)

上一篇主要讲了线程池的原理和实现,感觉有点意犹未尽,这篇文章是对上篇文章的一个补充,主要围绕以下两点展开,one-connection-per-thread的实现方式以及线程池中epoll的使用. one-connection-per-thread 根据scheduler_functions的模板,我们也可以列出one-connection-per-thread方式的几个关键函数. static scheduler_functions con_per_functions= {     max_c

android线程与线程池-----线程池(二)《android开发艺术与探索》

android 中的线程池 线程池的优点: 1 重用线程池中的线程,避免了线程的创建和销毁带来的性能开销 2 能有效的控制最大并发数,避免大量线程之间因为喜欢抢资源而导致阻塞 3 能够对线程进行简单的管理,提供定时执行以及指定间隔时间循环执行等 android 中的线程池源自java 中的Executor,Executor是一个接口,正真的实现是ThreadPoolExecutor. ThreadPoolExecutor 提供参数配置线程池. 下面是一个常用的构造方法: public Threa