Pool - 池
1. Story
给大家讲一个昭君创业的小故事:
昭君打算创业,做星际间客运,客户为高端有品格的外星人士
一开始,每来一个外星客户,勤劳的昭君就造一台豪华飞船,执行星际客运,每次执行完客运,飞船到达目的地之后,就地销毁
但是昭君的生意太好,有太多的UFO要造,消耗了大量的钢铁原料,和昭君宝贵的时间精力, 创业的昭君已不堪重荷
此时昭君发现每天的外星人客运量不超过50个,于是他想出了一个好办法,那就是创建一个最高容量为50个飞船的停飞场,不再就地销毁飞船,而是将飞船回收到停飞场,等下一客户要用的时候,就提出来直接使用!
从此昭君只要管理提飞船和回收飞船,只有当停飞场里,一架飞船都没有的时候,才不得不造船
有时候飞船已经被用的破破烂烂的(有时候则是因为有些外星人故意在飞船里拉粑粑),昭君检查飞船不能再投入使用后,就销毁它
有时候停飞场满了,昭君也不得不销毁回收的飞船
本来以为创业即将成功了,谁能想到忽然有人搞起了共享飞船,Shit!昭君的飞船租赁没有了用武之地,创业失败,于是昭君离开了这个让人伤心的地方
结果突然有一天,昭君走在街上被人打了一顿,原来自己当时造的几十架飞船占用了别人的地,导致人家没法开发外星人别野了,昭君连忙回去把剩下的几十架飞船都销毁了
创业真是不易啊
上面这个故事其实就是一个池的使用,池是用于解决 频繁发生的,消耗资源又费时的工作的问题(数据库连接,进程池),在日常的工作中也是经常用到,以下是一个Pool的基本结构,灰色为对应故事中的情节,帮助理解
2. Code
代码中的方法和属性都可以对应上图找到
package main
// ---------------Worker---------------
type Worker struct {
IsAvailable bool
}
// 创建
func InitWorker() *Worker {
return &Worker{}
}
// 执行
func (w *Worker)Process(){
}
// 销毁worker
func (w *Worker)Destory(){
// 消除之前占用的某一些资源
}
// --------------Pool---------------
type Pool struct {
availableWorker chan *Worker
}
// 创建Pool
func NewPool(maxsize int)Pool{
return Pool{
availableWorker:make(chan *Worker,maxsize), // 限制 bufferd chan 最大缓存数
}
}
// 获取worker
func (p *Pool) get()(w *Worker){
select{
case w = <-p.availableWorker: // 有可用的worker
default:
// 无可用的worker,创建(实在没船就创造船)
w = InitWorker()
}
return
}
// 回收worker
func (p *Pool) returnBack(w *Worker){
// worker 是否还可用(飞船是否还可用)
if !w.IsAvailable {
// 不可用,销毁丢弃
w.Destory()
return
}
select {
case p.availableWorker<-w: // 如果有位置,则缓存(停飞船喽)
default:
// 没位置,销毁丢弃
w.Destory()
}
}
// 销毁所有worker(不要重复昭君的惨剧)
func (p *Pool) destroyAllWorker(){
for {
select{
case w:= <-p.availableWorker:
w.Destory()
default:
return
}
}
}
// -------------- Let's go -----------------
func main() {
pool := NewPool(50) // 最大缓存50个worker(50个飞船的停飞场)
defer pool.destroyAllWorker() // 如果不想被追到街上打的话,最后记得销毁所有的工作者
for {
worker := pool.get() // 获取worker
worker.Process() // 使用worker
pool.returnBack(worker) // 归还worker
}
// 友情提示:该代码接近伪码,不知直接运行
}