string 是否线程安全

发布时间 2023-12-06 23:37:00作者: 李若盛开

线程安全是什么

线程安全是指在多线程环境下,程序的执行能够正确地处理多个线程并发访问共享数据的情况,保证程序的正确性和可靠性。

type StringHeader struct {
   Data uintptr  //存放指针,其指向具体的存储数据的内存区域
   Len  int     //字符串的长度
}

并发访问

package main
 
import (
 "fmt"
 "sync"
)
 
func main() {
 var wg sync.WaitGroup
 str := "脑子进煎鱼了"
 for i := 0; i < 5; i++ {
  wg.Add(1)
  go func() {
   defer wg.Done()
   fmt.Println(str)
  }()
 }
 wg.Wait()
}

定义了一个 string 变量 str,然后启动了 5 个 goroutine,每个 goroutine 都会输出 str 的值。由于 str 是不可变类型,因此在多个 goroutine 中并发访问它是安全的。

不可变类型,指的是一种不能被修改的数据类型,也称为值类型(value type)。不可变类型在创建后其值不能被改变,任何对它的修改操作都会返回一个新的值,而不会改变原有的值。

并发写入

func main() {
 var wg sync.WaitGroup
 str := "脑子进煎鱼了"
 for i := 0; i < 5; i++ {
  wg.Add(1)
  go func() {
   defer wg.Done()
   str += "" // 修改 str 变量
   fmt.Println(str)
  }()
 }
 wg.Wait()
}

在每个 goroutine 中向 str 变量中添加了一个感叹号。由于多个 goroutine 同时修改了 str 变量,因此可能会出现数据竞争的情况。

会发现程序输出结果会出现乱序或不一致的情况,可以确认 string 类型变量在多个 goroutine 中是不安全的。

string 实现线程安全

使用互斥锁(Mutex)来保护共享变量,确保同一时间只有一个goroutine 可以访问(互斥锁会带来一些性能上的开销)

 

【原子操作通常用于对基本类型(如整数、布尔值、指针等)的原子更改,而不是对字符串的修改】