介绍

在上一篇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. SpringBoot中拦截器和过滤器的使用

    一.拦截器 三种方式 继承WebMvcConfigurerAdapter   spring5.0 以弃用,不推荐 实现WebMvcConfigurer  推荐 继承WebMvcConfiguratio ...

  2. cloudfoundry service broker 制作

    实验室这边需要制作service broker.从今天开始将精力投入其中.

  3. Redis五种数据类型及应用场景

    MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加 ...

  4. TexturePacker贴图打包工具

    1.该软件是收费的,不过对于这么一款实用的工具来说,物有所值,下载地址 http://www.codeandweb.com/texturepacker 2.openGL载入纹理图片的时候,所用内存是会 ...

  5. 利用@factory和@dataProvider实现参数化

    利用构造函数将要用的的参数初始化,非常有利于简化脚本.它将外部的数据赋给本地的变量,可以使得初始化后的参数被其他方法使用.直接上代码: private String url;    private S ...

  6. [hihocoder][Offer收割]编程练习赛49

    相似颜色 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #includ ...

  7. hiho一下 第173周

    题目1 : A Game 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi and Little Ho are playing a game. Ther ...

  8. public static final 的用法

    public satic final 修饰后变量的名字全部用大写,定以后可以用类名直接访问,定义的变量不能被修改 所有的接口成员已经是静态,由于接口没有方法所有所以必须先赋值才行,可以直接用接口名调用 ...

  9. pandaboy Merry Christmas

  10. nginx强制使用https访问(多站点多域名配置)

    很多配置过https模板的人都知道,配置https 时 ,站在用户的角度http 和https 的区别根本不清楚.有时候敲 http 时会出现 404 错误,而实际上我们是https. 有朋友找我配置 ...