golang 创建一个简单的资源池,重用资源,减少GC负担

golang 创建一个简单的资源池,重用资源,减少GC负担,第1张

概述package main; import ( "sync" "errors" "fmt" ) //代码参考《Go语言实战》中第7章并发模式P
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();}

  

总结

以上是内存溢出为你收集整理的golang 创建一个简单的资源池,重用资源,减少GC负担全部内容,希望文章能够帮你解决golang 创建一个简单的资源池,重用资源,减少GC负担所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1271719.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存