在使用线程池时,当用线程池执行多个任务时,由于执行的任务时间过长,会导制两个任务互相执行,如果两个任务具有一定的操作顺序,可能会导制不同的操作结果,这时,就要将线程池按顺序操作。下面先给一段代码,该代码是不按顺序对线程池进行操作的,代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            AutoResetEvent autoEvent = new AutoResetEvent(false);

            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), autoEvent);

            ThreadPool.QueueUserWorkItem(new WaitCallback(WorkMethod), autoEvent);

            Console.ReadLine();

        }

        static void ThreadMethod(object stateInfo)

        {

            for (int i = 0; i < 100;i++ )

                Console.WriteLine("ThreadOne, executing ThreadMethod, " + "is {0}from the thread pool.", Thread.CurrentThread.IsThreadPoolThread ? "" : "not ");

        }

        static void WorkMethod(object stateInfo)

        {

            for (int i = 0; i < 100; i++)

                Console.WriteLine("ThreadTwo, executing WorkMethod");

        }

    }

}

运行结果如图1、图2所示。

图1  运行结果的上半部

图2  运行结果的下半部

从图1、图2可以看出,在使用线程池对线程进行操作时,由于各任务的时间过长,多个任务的线程可能会交互操作,那么,如何才能将线程池按指定的顺序进行操作呢?主要是用AutoResetEvent类来实现的。

可以用AutoResetEvent类的WaitOne方法阻止线程,然后只执行当前操作的线程池,当遇到AutoResetEvent类的Set方法后,将当前线程设置为终止状态,执行其他等待的线程。修改后的代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            AutoResetEvent autoEvent = new AutoResetEvent(false);

            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), autoEvent);

            autoEvent.WaitOne();

            ThreadPool.QueueUserWorkItem(new WaitCallback(WorkMethod), autoEvent);

            autoEvent.WaitOne();

            Console.ReadLine();

        } 

        static void ThreadMethod(object stateInfo)
{ for (int i = 0; i < 100;i++ ) Console.WriteLine("ThreadOne, executing ThreadMethod, " + "is {0}from the thread pool.", Thread.CurrentThread.IsThreadPoolThread ? "" : "not "); ((AutoResetEvent)stateInfo).Set(); } static void WorkMethod(object stateInfo) { for (int i = 0; i < 100; i++) Console.WriteLine("ThreadTwo, executing WorkMethod"); ((AutoResetEvent)stateInfo).Set(); } } }

运行结果如下:

C#中控制线程池的执行顺序的更多相关文章

  1. 探究ElasticSearch中的线程池实现

    探究ElasticSearch中的线程池实现 ElasticSearch里面各种操作都是基于线程池+回调实现的,所以这篇文章记录一下java.util.concurrent涉及线程池实现和Elasti ...

  2. 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法

    [源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...

  3. android中的线程池学习笔记

    阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...

  4. Android中的线程池

    在Android中,主线程不能执行耗时的操作,否则可能会导致ANR.那么,耗时操作应该在其它线程中执行.线程的创建和销毁都会有性能开销,创建过多的线程也会由于互相抢占系统资源而导致阻塞的现象.这个时候 ...

  5. mina2中的线程池

    一.Mina中的线程池模型 前面介绍了Mina总体的层次结构,那么在Mina里面是怎么使用Java NIO和进行线程调度的呢?这是提高IO处理性能的关键所在.Mina的线程调度原理主要如下图所示: A ...

  6. java并发编程(四) 线程池 & 任务执行、终止源码分析

    参考文档 线程池任务执行全过程:https://blog.csdn.net/wojiaolinaaa/article/details/51345789 线程池中断:https://www.cnblog ...

  7. JAVA中创建线程池的五种方法及比较

    之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...

  8. 戏(细)说Executor框架线程池任务执行全过程(上)

    一.前言 1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦.要执行任务的人只需把Task描述清楚,然后提交即可.这个Task是怎么被执行的,被谁执行的,什么时候执行的,提交的人就不 ...

  9. Spring中的线程池和定时任务功能

    1.功能介绍 Spring框架提供了线程池和定时任务执行的抽象接口:TaskExecutor和TaskScheduler来支持异步执行任务和定时执行任务功能.同时使用框架自己定义的抽象接口来屏蔽掉底层 ...

随机推荐

  1. Linux sed 批量替换多个文件中的字符串【转载】

    原文网址:http://blog.sina.com.cn/s/blog_730edb930100qzz5.html     比如,要将目录/modules下面所有文件中的zhangsan都修改成lis ...

  2. angularJs 指令的封装

    首先 指令的应用场景: 1:使你的html更具语义化,不需要深入研究代码就可以知道页面的大概逻辑. 2:抽象出一个自定义组件,在其他的地方进行重用. 一:directive的定义及其使用方法: 下面是 ...

  3. 机器学习:PCA(降噪)

    一.噪音 噪音产生的因素:可能是测量仪器的误差.也可能是人为误差.或者测试方法有问题等: 降噪作用:方便数据的可视化,使用样本特征更清晰:便于算法操作数据: 具体操作:从 n 维降到 k 维,再讲降维 ...

  4. rails的respond to format

    Here are all the default Rails Mime Types: "*/*" => :all "text/plain" => : ...

  5. SQLServer数据库中开启CDC导致事务日志空间被占满的原因

    SQLServer数据库中开启CDC导致事务日志空间被占满的原因 转载  2017-04-01   投稿:mrr    我要评论 这篇文章主要介绍了SQLServer数据库中开启CDC导致事务日志空间 ...

  6. java代码调用数据库存储过程

    由于前边有写java代码调用数据库,感觉应该把java调用存储过程也写一下,所以笔者补充该篇! package testSpring; import java.sql.CallableStatemen ...

  7. openGL一些概念01

    顶点数据: 顶点数据是一系列顶点的集合. 一个顶点(Vertex)是一个3d坐标的数据的集合. 而顶点数据是用顶点属性(Vertex Attribute)表示的,它可以包含任何我们想用的数据. (但是 ...

  8. DAY11-MYSQL之ORM框架SQLAlchemy

    一 介绍 SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取 ...

  9. 关于uboot的一些优化

    转载于:http://blog.163.com/solylee@126/blog/static/1718231572010101910485331/ 本人的开发环境是u-boot-1.1.6版本,fe ...

  10. js原型及原型链

    一. 普通对象与函数对象  JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object ,Function 是JS自带的函数对象.下面举例说明 function f ...