博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang 创建一个简单的资源池,重用资源,减少GC负担
阅读量:6319 次
发布时间:2019-06-22

本文共 2222 字,大约阅读时间需要 7 分钟。

package main;import (	"sync"	"errors"	"fmt")//代码参考《Go语言实战》中第7章并发模式Pool//如果哪个类型实现了Resource接口中的两个方法,我们就认为该类型是资源type Resource interface {	Close();	IsClosed() bool;}//工厂方法,用于创建新资源type Factory func() (Resource, error)//资源池type ResourcePool struct {	//互斥锁,保证池中资源的安全	mu sync.Mutex;	//通道,用于保存资源	res chan Resource;	//工厂方法	factory Factory;	//判断资源池是否关闭	closed bool;}//创建一个资源池func NewResourcePool(factory Factory, cap int) (*ResourcePool, error) {	if cap > 0 {		return &ResourcePool{			mu:      sync.Mutex{},			res:     make(chan Resource, cap),			factory: factory,			closed:  false,		}, nil;	}	return nil, errors.New("cap应大于0");}//从资源池中获取一个资源func (rp *ResourcePool) Get() (Resource, error) {	if rp.closed {		return nil, errors.New("资源池已关闭");	}	select {	//获取资源,判断通道是否关闭	case item, ok := <-rp.res:		{			if !ok {				return nil, errors.New("资源池已关闭");			}			return item, nil;		}	default:		{			//返回工厂创建的资源			return rp.factory();		}	}}//将资源放入池中func (rp *ResourcePool) Put(res Resource) error {	if rp.closed {		return errors.New("资源池已关闭");	}	select {	//当res无法插入时,这里会阻塞,select执行default	case rp.res <- res:		{			return nil;		}	default:		{			res.Close();			return errors.New("资源池已满");		}	}}//关闭资源池func (rp *ResourcePool) Close() {	if rp.closed {		return;	}	rp.mu.Lock();	//关闭资源池	rp.closed = true;	//关闭通道,不在往通道中添加新资源	close(rp.res);	//循环关闭通道中的资源	for item := range rp.res {		if !item.IsClosed() {			item.Close();		}	}	rp.mu.Unlock();}//自定义一个资源类型type Data struct {	data []byte;}func (d Data) Close() {	d.data = nil;}func (d Data) IsClosed() bool {	if len(d.data) > 0 {		return true;	} else {		return false;	}}func (d Data) Write(b []byte) {	copy(d.data, b);}func main() {	//创建一个资源池	pool, _ := NewResourcePool(func() (Resource, error) {		return Data{			data: make([]byte, 16),		}, nil;	}, 3);	//获取资源	item1, _ := pool.Get();	item1.(Data).Write([]byte("123"));	item2, _ := pool.Get();	item2.(Data).Write([]byte("456"));	item3, _ := pool.Get();	item3.(Data).Write([]byte("789"));	fmt.Println(item1);	fmt.Println(item2);	fmt.Println(item3);	//我们再获取一个资源	item4, _ := pool.Get();	//我们把源资入回池中	pool.Put(item1);	pool.Put(item2);	pool.Put(item3);	//这里就会报错了,因为我们创建池时,设置的大小为3	err := pool.Put(item4);	if err != nil {		fmt.Println(err);	}	//关闭资源池	pool.Close();}

  

转载地址:http://nacaa.baihongyu.com/

你可能感兴趣的文章
Notepad++配置Python开发环境
查看>>
用户组概念 和 挂载 概念
查看>>
AspNetPager控件的最基本用法
查看>>
sessionKey
查看>>
高性能Javascript--脚本的无阻塞加载策略
查看>>
Java 编程的动态性, 第4部分: 用 Javassist 进行类转换--转载
查看>>
完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三
查看>>
iOS8 Push Notifications
查看>>
各大名企笔试及面经大全(程序猿必读)
查看>>
Oracle 连接、会话数的查看,修改
查看>>
Oracle 11g password过期被锁定报道 ORA-28000 the account is locked
查看>>
轨磁条简介
查看>>
大厂前端高频面试问题与答案精选
查看>>
如何设计高扩展的在线网页制作平台
查看>>
Git 2.5增加了工作树、改进了三角工作流、性能等诸多方面
查看>>
深度揭秘腾讯云低功耗广域物联网LPWAN 技术及应用
查看>>
与Jeff Sutherland谈敏捷领导力
查看>>
More than React(四)HTML也可以静态编译?
查看>>
React Native最佳学习模版- F8 App开源了
查看>>
云服务正在吞噬世界!
查看>>