关于线程池的一些思路
今天无意中,看了一个线程池实现的源代码,感觉这样的实现思路确实活灵活现,贴近生活。
在网络中概要了线程池的优点:“在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。”
可以这样来实现线程池:
ThreadPool 用于创建并管理线程池其方法大致如下:
virtual void AddTask(Task *task) = 0;
virtual void RemoveTask() = 0;
virtual bool ShutDown( ) = 0;
virtual bool IsShutDown() const = 0;
virtual bool Start(long size) = 0;
virtual long GetPoolSize() const = 0;
virtual void Suspend() = 0;
virtual void Resume() = 0;
因为其中包含了一个线程的size,因此,也可以利用Resize()重新定义线程池的大小。
工作线程(WorkThread): 线程池中线程
它应该包含指向线程池的指针,并且包含了线程本身的Start、Suspend、Resume等操作。
线程函数应该是一个体内包含while循环的函数,如果当前线程池没有任务就等待,如果线程池中加入了任务,就自动唤醒该线程,如果接收到线程池释放等的消息,则自动消会,清理回收资源。
Task类是具体要处理的任务的一个抽象接口
//任务开始之前调用,可以在这做一些初始化工作 virtual void OnBegin(){} //任务结束之后调用,可以在这做一些清理工作 virtual void OnEnd() {} //覆盖它,做具体的任务处理 virtual unsigned long Run(PoolStateNotify*) = 0;
大体以上的思路就是比较直观的线程池的简单实现。
就好比移动公司的服务台可比拟成线程池(Threadpool),里面的接电话的小姐(好像都很漂亮哦)可以看成是不同的线程(workthread)(太残酷了点),我们打电话咨询各种业务可以看成是不同任务(task)。作为刚刚毕业的大学生可以到移动公司(Threadpool)应聘,当你接到offer后,就会成为接话员(thread)(恐怕对于刚毕业的我们应该不会太容易接受这样的现实)…… 这样建立起来的这种机制以后。接话员的工作就是每天按时上班,没事的时候可以看看杂志,听听音乐(sleep状态),一旦电话响起(Task来了),他们就必须拿起电话提供服务(即便是联通的卡被猫吃了这样的问题他们也必须提供必要的帮助),假设一共有50个接话员,而同时有60个人打电话咨询,那么就会有10个倒霉蛋需要等待---------这段描述过程基本就是线程池的一个工作原理。