当前位置: 首页 > 编程日记 > 正文

Golang中Buffer高效拼接字符串以及自定义线程安全Buffer

本文原创文章,转载注明出处,博客地址 https://segmentfault.com/u/to... 第一时间看后续精彩文章。觉得好的话,顺手分享到朋友圈吧,感谢支持。

Go中可以使用“+”合并字符串,但是这种合并方式效率非常低,每合并一次,都是创建一个新的字符串,就必须遍历复制一次字符串。Java中提供StringBuilder类(最高效,线程不安全)来解决这个问题。Go中也有类似的机制,那就是Buffer(线程不安全)。

以下是示例代码:
package mainimport ("bytes""fmt"
)func main() {var buffer bytes.Bufferfor i := 0; i < 1000; i++ {buffer.WriteString("a")}fmt.Println(buffer.String())
}

使用bytes.Buffer来组装字符串,不需要复制,只需要将添加的字符串放在缓存末尾即可。

Buffer为什么线程不安全?

The Go documentation follows a simple rule: If it is not explicitly stated that concurrent access to something is safe, it is not.

==Go文档遵循一个简单的规则:如果没有明确声明并发访问某事物是安全的,则不是。==

以下是Golang中bytes.Buffer部分源码
// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {buf       []byte   // contents are the bytes buf[off : len(buf)]off       int      // read at &buf[off], write at &buf[len(buf)]bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.lastRead  readOp   // last read operation, so that Unread* can work correctly.
}// Write appends the contents of p to the buffer, growing the buffer as
// needed. The return value n is the length of p; err is always nil. If the
// buffer becomes too large, Write will panic with ErrTooLarge.
func (b *Buffer) Write(p []byte) (n int, err error) {b.lastRead = opInvalidm := b.grow(len(p))return copy(b.buf[m:], p), nil
}// Read reads the next len(p) bytes from the buffer or until the buffer
// is drained. The return value n is the number of bytes read. If the
// buffer has no data to return, err is io.EOF (unless len(p) is zero);
// otherwise it is nil.
func (b *Buffer) Read(p []byte) (n int, err error) {b.lastRead = opInvalidif b.off >= len(b.buf) {// Buffer is empty, reset to recover space.b.Truncate(0)if len(p) == 0 {return}return 0, io.EOF}n = copy(p, b.buf[b.off:])b.off += nif n > 0 {b.lastRead = opRead}return
}

源码对于Buffer的定义中,并没有关于锁的字段,在write和read函数中也未发现锁的踪影,所以符合上面提到的文档中的rule,即Buffer并发是不安全的

如何自定义实现一个并发安全的Buffer

type Buffer struct {b bytes.Bufferrw sync.RWMutex
}
func (b *Buffer) Read(p []byte) (n int, err error) {b.rw.RLock()defer b.rw.RUnlock()return b.b.Read(p)
}
func (b *Buffer) Write(p []byte) (n int, err error) {b.rw.Lock()defer b.rw.Unlock()return b.b.Write(p)
}

通过读写锁,解决并发读写问题,以上提供了Read和Write函数,亲,是不是Golang代码简洁明了?其它函数可以在Golang关于Buffer源码的基础上自行实现

两种锁的区别
sync.Mutex(互斥锁)sync.RWMutex(读写锁)
当一个goroutine访问的时候,其他goroutine都不能访问,保证了资源的同步,避免了竞争,不过也降低了性能非写状态时:多个Goroutine可以同时读,一个Goroutine写的时候,其它Goroutine不能读也不能写,性能好

相关文章:

Python培训之就业面试题分享

近几年&#xff0c;学习Python编程的人越来越多&#xff0c;大家对于Python编程技术非常感兴趣&#xff0c;想要转型到这个行业&#xff0c;下面小编为大家整理一份Python找工作的面试题分享&#xff0c;希望能够帮助正在找Python工作的小伙们。 Python培训之就业面试题分享&am…

IHttpHandler 概述

IHttpHandler 概述可能和我一样&#xff0c;很多Asp.Net开发人员都有过Asp的背景&#xff0c;以至于我们在开发程序的时候&#xff0c;通常都是在“页面级”上思考&#xff0c;也就是说我们现在正在做的这个页面应该有什么样的功能&#xff0c;是进行一个问卷调查还是一个数据库…

LeetCode实战:有效的括号

题目英文 Given a string containing just the characters ‘(’, ‘)’, ‘{’, ‘}’, ‘[’ and ‘]’, determine if the input string is valid. An input string is valid if: Open brackets must be closed by the same type of brackets.Open brackets must be clos…

linux下的vi与vim

vi与vimvi编辑器是所有Unix及Linux系统下标准的编辑器&#xff0c;他就相当于windows系统中的记事本一样&#xff0c;它的强大不逊色于任何最新的文本编辑器。他是我们使用Linux系统不能缺少的工具。由于对Unix及Linux系统的任何版本&#xff0c;vi编辑器是完全相同的&#xff…

零基础该如何学习Web前端知识?

想要跳槽到IT行业人在近几年越来越多&#xff0c;大部分都是想要学习web前端技术&#xff0c;但是这其中有很多都是零基础学员&#xff0c;大家都想知道零基础该如何学习Web前端知识?我们来看看下面的详细介绍。 零基础该如何学习Web前端知识? 1、Web前端学习步骤 (1)HTML标签…

刻意练习:Python基础 -- Task05. 函数与Lambda表达式

背景 我们准备利用17天时间&#xff0c;将 “Python基础的刻意练习” 分为如下任务&#xff1a; Task01&#xff1a;变量、运算符与数据类型&#xff08;1day&#xff09;Task02&#xff1a;条件与循环&#xff08;1day&#xff09;Task03&#xff1a;列表与元组&#xff08;…

PHP 实现无限分类

最近打算做一个blog&#xff0c;通常每篇文章都有属于自己的分类。下面就记录下我在写blog时实现无限分类的过程。php框架用的是laravel,根据注释也能轻松改成你习惯的框架。 数据表设计 CREATE TABLE article_category (id int(10) unsigned NOT NULL AUTO_INCREMENT,pid int(…

软件测试培训怎么学?有没有发展前景?

软件测试是最近几年广受大家关注的一个编程技术&#xff0c;软件测试的出现也是因软件的存在而存在的&#xff0c;目前很多人都想知道软件测试培训怎么学?有没有发展前景?我们来看看下面的详细介绍。 软件测试需要学测试环境(网络环境&#xff0c;windows环境等)、数据库管理…

LeetCode实战:最长有效括号

题目英文 Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring. Example 1: Input: "(()" Output: 2 Explanation: The longest valid parentheses substring is "(…

Android选项卡置底的方法

发现很多Android应用的选项卡 都是显示在页面底部的&#xff0c;网上有资料&#xff1a;通过反射获取TabWidget中的私有变量&#xff0c;改变其值。今天反编译了腾讯微薄&#xff0c;发现实现这个很简单, 只需将布局文件中<TabWidget />标签加个android:layout_gravity&…

【iCore4 双核心板_ARM】例程十七:USB_MSC实验——读/写U盘(大容量存储器)

实验方法&#xff1a; 1、将跳线冒跳至USB_UART,通过Micro USB 线将iCore4 USB-UART接口与电脑相连。 2、打开PUTTY软件。 3、通过读U盘转接线将U盘&#xff08;或者读卡器&#xff09;与iCore4 USB-OTG接口相连。大容量存储器为FAT32格式。 实验现象&#xff1a; 核心代码&…

软件测试技术篇:UI自动化到底是难是易?

UI自动化技术&#xff0c;是我们测试工程师绕不开的一个话题&#xff0c;只要提起它来&#xff0c;基本所有测试工程师都能给你说道说道。 有些人认为它很难&#xff0c;有些人认为它很简单。认为它很难的人会告诉你&#xff0c;UI自动化非常不稳定&#xff0c;太难了&#xff…

获取DataRow某列的值的封装

public class DataHelper{const string DEFSTR "";/// <summary>/// 根据一个类型&#xff0c;获取其默认值&#xff0c;数字默认是为0&#xff0c;字符串默认值为一个空字符串/// </summary>/// <typeparam name"T"></typeparam>…

LeetCode实战:逆波兰表达式求值

题目英文 Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are , -, *, /. Each operand may be an integer or another expression. Note: Division between two integers should truncate toward zero.The given RPN expre…

Python函数式编程-map/reduce

1.map map()传入的第一个参数是f&#xff0c;即函数对象本身。 map()函数接收两个参数&#xff0c;一个是函数&#xff0c;一个是Interable&#xff0c;map将传入的函数依次作用到序列的每个元素&#xff0c;并把结果作为新的Iterator返回。 >>> def f(x): ... re…

Java程序员到什么级别可以去BAT上班?

学习java技术&#xff0c;很多人都想要进入到IT行业&#xff0c;如果跳槽到BAT大厂上班&#xff0c;那更是非常好的&#xff0c;近几年学习java技术的人越来越多&#xff0c;那么Java程序员到什么级别可以去BAT上班?来看看下面的详细介绍。 Java程序员到什么级别可以去BAT上班…

Android开发之SharedPreferences的封装

对于大部分初学者来说&#xff0c;如果想利用SharedPreferences进行数据存储的话大部分人(包括本人)应该会这样&#xff1a; 存储&#xff1a; SharedPreferences sharedPreferences getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); Editor editor …

LeetCode实战:设计循环双端队列

题目英文 Design your implementation of the circular double-ended queue (deque). Your implementation should support following operations: MyCircularDeque(k): Constructor, set the size of the deque to be k.insertFront(): Adds an item at the front of Deque…

ItemsControl 解析

先上个示例 <ItemsControl Margin"10" ItemsSource"{Binding}" Name"itemsControl"> <ItemsControl.Template><ControlTemplate TargetType"{x:Type ItemsControl}"><Border CornerRadius"5">&l…

【Web前端培训基础知识】ES5及ES6this详解

今天&#xff0c;我们学习一下JavaScript中的this。我们从什么是this,ES5及ES6中this的几种情况进行学习。让this变的so easy&#xff0c;我们这里说的都是非严格模式下。 什么是this this表示当前行为执行的主体&#xff0c;在javaScript中this不是函数独有的&#xff0c;但是…

LeetCode实战:滑动窗口最大值

题目英文 Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sli…

Partial Class部分类

Partial Class &#xff0c;部分类 或者分布类。顾名思义&#xff0c;就是将一个类分成多个部分。比如说&#xff1a;一个类中有3个方法&#xff0c;在VS 2005将该类中3个方法分别存放在3个不同的.cs文件中。这样做的好处&#xff1a;1、一个大型的项目类可以同时分成不同的区块…

表格中td限宽溢出以省略号代替

table.ms-listviewtable {table-layout:fixed;width: 100%; } table.ms-listviewtable td[role"gridcell"]{white-space:nowrap;text-overflow:ellipsis;-moz-text-overflow: ellipsis;overflow:hidden; } 转载于:https://www.cnblogs.com/JaneBlog/p/7490445.html

【UI设计培训基础知识】设计中的点线面-线

UI设计所要学习的知识有很多&#xff0c;想要在后期的工作中稳稳当当&#xff0c;基础知识一定要扎实&#xff0c;下面就是小编为大家整理的一份关于UI设计培训基础知识的相关内容&#xff0c;主要讲的是设计中的点线面-线&#xff0c;来看看下面的详细资料吧。 点的移动形成一…

场面话大全,绝对受用一生

◆ 父母生日祝酒辞 尊敬的各位领导、各们长辈、各们亲朋好友&#xff1a;大家好&#xff01; 在这喜庆的日子里&#xff0c;我们高兴地迎来了敬爱的父亲&#xff08;母亲&#xff09;XX岁的生日。今天&#xff0c;我们欢聚一堂&#xff0c;举行父亲&#xff08;母亲&#xff09…

LeetCode实战:爬楼梯

题目英文 You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? Note: Given n will be a positive integer. Example 1: Input: 2 Output: 2 Exp…

Visual Studio Remote Debugger(for 2005/2008) .net远程调试转

我采用虚机的方式模拟了局域网环境&#xff0c;以下是我操作的步骤&#xff08;client代表客户端&#xff0c;server代表调试机&#xff09;&#xff1a; 建立ASP.NET项目(client)&#xff1a;简单写了点Code 代码 1 protectedvoidPage_Load(objectsender, EventArgs e)2 {3 in…

UI设计师必备技能,看看你都学会了吗?

想要成为一名合格的UI设计师&#xff0c;是要有这几项必备技能的&#xff0c;学会这些必备技能&#xff0c;那么后期的工作会进行的相当顺利&#xff0c;下面小编就为大家详细的介绍一下UI设计师必备技能都有哪些? UI设计师必备技能&#xff0c;看看你都学会了吗? 1、设计软件…

CSS中关于清除浮动的问题

1.采用:after的方法清除浮动 优点&#xff1a;避免在html里插入多余的标签 详情&#xff1a;http://www.positioniseverything.net/easyclearing.html 整理成一个通用的.clearfix .clearfix:after {content:".";display:block;height:0;clear:both;visibility:hidden…

LeetCode实战:x 的平方根

题目英文 Implement int sqrt(int x). Compute and return the square root of x, where x is guaranteed to be a non-negative integer. Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned. …