介绍

在上一篇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);
}

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1anVueHh4eHg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

方法二

我们不是用信号量。我们使用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的时候才继续下去


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

  1. juc线程池原理(二):ThreadPoolExecutor的成员变量介绍

    概要 线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析ThreadPoolExecutor类,来了解线程池的原理. ThreadPoolExecutor数据结构 Thread ...

  2. Java 线程池(二)

    简介 在上篇 Java 线程池(一) 我们介绍了线程池中一些的重要参数和具体含义,这篇我们看一看在 Java 中是如何去实现线程池的,要想用好线程池,只知其然是远远不够的,我们需要深入实现源码去了解线 ...

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

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  4. java线程池技术(二): 核心ThreadPoolExecutor介绍

    版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程池技术属于比较"古老"而又比较基础的技术了,本篇博客主要作用是个人技术梳理,没什么新玩意. 一.Java线程池技术的 ...

  5. Java之线程池(二)

    关于线程和线程池的学习,我们可以从以下几个方面入手: 第一,什么是线程,线程和进程的区别是什么 第二,线程中的基本概念,线程的生命周期 第三,单线程和多线程 第四,线程池的原理解析 第五,常见的几种线 ...

  6. 线程池系列二:ThreadPoolExecutor讲解

    一.简介 1)线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, i ...

  7. 线程池系列二:一张动图,彻底懂了execute和submit

    ​ 我们知道线程池通过execute方法执行提交的Runnable任务,但Runnable只是执行任务,没有返回任何信息. [线程池原理:线程池原来是个外包公司,打工人我悟了] 若是我们想在异步执行完 ...

  8. Android线程池(二)

    本篇主要介绍Android自带的线程池的管理. 包含开始任务.重新加载.添加删除任务等,示例代码如下: package com.jiao.threadpooltest; import java.uti ...

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

    android 中的线程池 线程池的优点: 1 重用线程池中的线程,避免了线程的创建和销毁带来的性能开销 2 能有效的控制最大并发数,避免大量线程之间因为喜欢抢资源而导致阻塞 3 能够对线程进行简单的 ...

随机推荐

  1. HDU 2520 我是菜鸟我怕谁

    2019-05-27 17:52:01 加油!!! 看题时候就要仔细,最后容易忘记%10000 #include <bits/stdc++.h> using namespace std; ...

  2. C# 同步更新系统时间

    前言 在定位用户问题时,发现有些电脑,会出现系统时间不是最新的问题. 可能原因: 取消了勾选服务器时间同步 当前安装的系统,是一个未知来源系统,导致系统时间更新失败 而系统时间不正确,会导致IE选项- ...

  3. js与jquery基础知识对比(一)---2017-05-06

    用表格做的,想要对比的内容一目了然,红色部分为重点   js jquery 取元素 id: document.getElementById("aa"); 取到的是dom对象 cla ...

  4. TYVJ 1427 线段树的基本操作

    题意: 单点修改,区间最值 思路: 线段树 原题请戳这里 //By SiriusRen #include <cstdio> #include <cstring> #includ ...

  5. Super超级ERP系统---(3)基础信息管理--商品管理

    商品管理主要包括商品的添加,修改,维护商品所在分类,单位,供应商,品牌,名称,价格,尺寸,规格等属性的维护.   1.商品添加 2.商品列表展示 商品列表界面左侧商品分类,右侧是商品信息

  6. GCC G++ Make CMake自我科普

    Linux下gcc g++ make cmake 联系和区别 C/C++程序从编写到可执行一般经历这几个阶段 编写源代码 编译器编译代码生成目标文件,如.o文件 链接器链接目标文件和其他目标文件/库文 ...

  7. 项目随笔@Service("testService")-------第二篇

    在springmvc中使用注解已经司空见惯了,今天见到了@Service("xxx")这种形式,让我大吃一惊.原来在service后面可以加参数,作为该service的名字,在sp ...

  8. python 整型,布尔值,字符串相关

    1.整型(int) 就是所有整数, 2.布尔值(bool) True False 0,"",[],{},(),none为False 3.字符串(str) 字符: 是单一文字符号 字 ...

  9. HILLSTONE sg6000 g5150 怎么恢复出厂设置

    hillstone恢复出厂设置的方法(忘记密码的情况) 口令丢失情况下的处理 如果口令丢失,用户无法登录安全路由器进行配置,请在安全路由器刚启动时按住 CLR 按键大约 5 秒,使设备恢复到出厂配置. ...

  10. JS 输入年份,再输入月份,弹出这个月有多少天?

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...