• 推荐
  • 评论
  • 收藏

线程池 vs 专有线程

2022-11-17    7324次浏览

首先,解释一下[专有线程]这里我所表达的意思:就是对某一类任务(即调用同一个方法)用一个Thread,然后在自己封装一个处理列表,通过这一个线程循环处理任务。这里我给出我的代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace POET.Common
{
    /// <summary>
    /// @author: gxjiang
    /// @date  : 2011/4/7
    /// @description : 提供一个专有的线程封装,使得这个线程可以去处理一系列的事情。
    /// </summary>
    public class ExclusiveThread<T>
    {
        /// <summary>
        /// 任务列表
        /// </summary>
        private Queue<T> TaskQueue = new Queue<T>();
        /// <summary>
        /// 是否被停止
        /// </summary>
        private bool IsStopped = false;
        /// <summary>
        /// 处理的线程
        /// </summary>
        private Thread InnerThread; 
        /// <summary>
        /// 出队列时处理方法
        /// </summary>
        private DequeueHandler CallBack;

        public delegate void DequeueHandler(T item);
        /// <summary>
        /// 线程停止事件
        /// </summary>
        public event EventHandler Stopped;

        public ExclusiveThread(DequeueHandler callBackFunc)
        {
            this.CallBack = callBackFunc;
            this.CreateInnerThread();
        }
            
        private void ThreadFunction()
        {
            while (true)
            {
                lock (this.TaskQueue)
                {
                    if (this.TaskQueue.Count > 0)
                    {
                        T item = this.TaskQueue.Dequeue();
                        this.OnDequeue(item);
                    }
                    else
                    {
                        if (this.IsStopped)
                            this.OnStop();
                        break;
                    }
                }
            }
        }

        private void OnStop()
        {
            EventHandler handler = Stopped;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        private void OnDequeue(T item)
        {
            if (this.CallBack != null)
                this.CallBack(item);
        }

        private void AbortInnerThread()
        {
            try
            {
                if (this.InnerThread != null)
                    this.InnerThread.Abort();
            }
            catch
            {
            }
        }

        private void CreateInnerThread()
        {
            this.InnerThread = new Thread(new ThreadStart(ThreadFunction));
        }

        private void InnerThreadAction()
        {
            if (this.InnerThread.ThreadState == ThreadState.Unstarted) this.InnerThread.Start();
            else if (this.InnerThread.ThreadState == ThreadState.Stopped || this.InnerThread.ThreadState == ThreadState.Aborted)
            {
                this.CreateInnerThread();
                this.InnerThread.Start();
            }
        }

        /// <summary>
        /// 增加处理任务
        /// 若线程么有启动则启动
        /// 若已经启动就添加到任务队列中
        /// 若任务处理完了,则挂起线程
        /// </summary>
        /// <param name="item">处理任务</param>
        public void Add(T item)
        {
            if (this.IsStopped) 
                throw new ExclusiveThreadException("此线程已经停止,不可以再添加任务。");
            lock (this.TaskQueue)
            {
                this.TaskQueue.Enqueue(item);
                this.InnerThreadAction();
            }
        }

        /// <summary>
        /// 停止处理任务,触发Stopped事件
        /// </summary>
        public void Stop()
        {
            lock (this.TaskQueue)
            {
                this.IsStopped = true;
                if (this.TaskQueue.Count == 0 && this.InnerThread.ThreadState == ThreadState.Stopped)
                    this.OnStop();
            }
        }

        /// <summary>
        /// 重新开始任务,之后调用[Add]方法加任务
        /// </summary>
        public void Resume()
        {
            this.IsStopped = false;
        }
    }

    /// <summary>
    /// 自定义异常
    /// </summary>
    public class ExclusiveThreadException : ApplicationException
    {
        public ExclusiveThreadException():base() { }
        public ExclusiveThreadException(string msg) : base(msg) { }
        public ExclusiveThreadException(string msg, Exception innerException) : base(msg, innerException) { }
    }

    
}

在这个线程的包装类中,我称之为专有线程或者定制线程,我可以把很多相同的任务放在这个队列中,让这一个线程循环处理。

     另一个方式是用线程池(ThreadPool),这个我也想过去用,可是我个人觉得并不是所有时候都能用,因为有时候还是得考虑一下线程的执行先后顺序。

     这里我提出来这个问题?到底是线程池去处理很多的线程较好?还是用我这种专有线程去处理一类任务?各有什么缺憾之处呢?

     希望大家给予讨论!

原文地址:https://www.cnblogs.com/Leo_wl/p/2008886.html