C#有ThreadPool和Task,为什么还要自己写线程池?我以前也没想过自己写线程池,都是用ThreadPool或Task,前段时间写爬虫,我想控制10个线程爬网页、10个线程下载网页上的图片,不然的话因为网页很多,图片相对较少,可能大部分线程都在爬网页,少量线程在下载图片,这样下载图片的速度慢了,所以我想到了自己写线程池MyThreadPool,再配合ThreadPool使用,精确控制爬网页和下载图片的线程数。不过这个线程池写的比较简单,缺点是线程池会瞬间创建最大数量的工作线程。

 

线程池类代码:

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

namespace Utils
{
    /// <summary>
    /// 线程池
    /// </summary>
    public static class MyThreadPool
    {
        /// <summary>
        /// 最大工作线程数
        /// </summary>
        private static int m_WorkerThreads = 5;
        /// <summary>
        /// 线程队列
        /// </summary>
        private static ConcurrentQueue<MyThread> m_ThreadQueue = new ConcurrentQueue<MyThread>();
        /// <summary>
        /// 任务队列
        /// </summary>
        private static ConcurrentQueue<Tuple<Action<object>, object>> m_Action = new ConcurrentQueue<Tuple<Action<object>, object>>();

        /// <summary>
        /// 创建并启动线程
        /// </summary>
        /// <param name="action"></param>
        /// <param name="obj"></param>
        public static void Start(Action<object> action, object obj = null)
        {
            m_Action.Enqueue(new Tuple<Action<object>, object>(action, obj));

            MyThread thread;
            if (m_ThreadQueue.Count < m_WorkerThreads)
            {
                thread = new MyThread();
                m_ThreadQueue.Enqueue(thread);
                thread.isWorker = true; //设置为工作线程
                thread.thread = new Thread(new ThreadStart(() =>
                {
                    Tuple<Action<object>, object> tuple;
                    while (thread.isWorker) //如果是工作线程,则一直循环
                    {
                        if (m_Action.TryDequeue(out tuple)) //如果任务队列中有任务,则取出任务执行
                        {
                            tuple.Item1(tuple.Item2); //执行任务
                        }
                        else
                        {
                            Thread.Sleep(100);
                        }
                        Thread.Sleep(1);
                    }
                }));
                thread.thread.IsBackground = true;
                thread.thread.Start();
            }
        }

        /// <summary>
        /// 设置最大工作线程数
        /// </summary>
        /// <param name="workerThreads">最大工作线程数</param>
        public static void SetMaxThreads(int workerThreads)
        {
            m_WorkerThreads = workerThreads;
            MyThread thread = null;
            while (m_ThreadQueue.Count > m_WorkerThreads)
            {
                m_ThreadQueue.TryDequeue(out thread);
                thread.isWorker = false;
                Thread.Sleep(1);
            }
        }

        /// <summary>
        /// 获取最大工作线程数
        /// </summary>
        public static int GetMaxThreads()
        {
            return m_WorkerThreads;
        }

        /// <summary>
        /// 获取当前工作线程数
        /// </summary>
        public static int GetWorkerThreads()
        {
            return m_ThreadQueue.Count;
        }
    }

    /// <summary>
    /// 线程
    /// </summary>
    public class MyThread
    {
        /// <summary>
        /// 线程
        /// </summary>
        public Thread thread { get; set; }
        /// <summary>
        /// 是否工作线程
        /// </summary>
        public bool isWorker { get; set; }
    }
}
View Code

相关文章:

  • 2021-10-26
  • 2022-12-23
  • 2021-08-04
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-09-27
  • 2021-12-17
  • 2021-10-12
  • 2021-11-05
  • 2021-11-08
  • 2022-12-23
相关资源
相似解决方案