缓冲通道实现可复用的对象池
type reusableobj struct{}
type objpool struct {
bufchan chan *reusableobj
}
func newobjpool(numofobj int) *objpool {
objpool := objpool{}
objpool.bufchan = make(chan *reusableobj, numofobj)
for i := 0; i < numofobj; i++ {
objpool.bufchan <- &reusableobj{}
}
return &objpool
}
func (p *objpool) getobj(timeout time.Duration) (*reusableobj, error) {
select {
case ret := <-p.bufchan:
return ret, nil
case <-time.After(timeout):
return nil, errors.New("time out")
}
}
func (p *objpool) releaseobj(obj *reusableobj) error {
select {
case p.bufchan <- obj:
return nil
// 放不进去了就会返回overflow
default:
return errors.New("overflow")
}
}
func main() {
pool := newobjpool(10)
// if err := pool.releaseobj(&reusableobj{}); err != nil {
// fmt.Println(err)
// }
for i := 0; i < 11; i++ {
if v, err := pool.getobj(time.Second); err != nil {
fmt.Println(err)
} else {
fmt.Println(v)
if err := pool.releaseobj(v); err != nil {
fmt.Println(err)
}
}
}
fmt.Println("done.")
}
缓冲通道实现一个可复用缓存队列
客户端协程执行一个无限循环从某个源头接收数据,数据读取到Buffer类型的缓冲区。为了避免分配过多的缓冲区以及释放缓冲区,它保留了一份空闲缓冲区列表。
// 可重用的缓冲区队列(freeList)与服务器是共享的
// 当接收数据时,客户端尝试从freeList获取缓冲区
// 但如果此时通道为空,则会分配新的缓冲区。
var freeList = make(chan *Buffer, 100)
var serverChan = make(chan *Buffer)
func client() {
for {
var b *Buffer
// Grab a buffer if available; allocate if not
select {
case b = <-freeList:
// Got one; nothing more to do
default:
// None free, so allocate a new one
b = new(Buffer)
}
loadInto(b) // Read next message from the network
serverChan <- b // Send to server
}
}
func server() {
for {
b := <-serverChan // Wait for work.
process(b)
// Reuse buffer if there's room.
select {
case freeList <- b:
// Reuse buffer if free slot on freeList; nothing more to do
default:
// Free list full, just carry on: the buffer is 'dropped'
}
}
}