当前位置: 首页 > 面试题库 >

字符串和并发性的不变性

郭永安
2023-03-14
问题内容

我们应该在编写字符串上进行同步吗?因为字符串是不可变的,所以我们永远不会在两个不同线程的读写之间获得不一致的状态,对吗?

换句话说,为什么我们没有字符串类型的原子?


问题答案:

string值是不可变的,但变量不是。变量就是 变量 ,顾名思义, 变量 的值可以更改。

您不需要同步就可以访问一个string不变的值。如果将string值传递给您,则该值(的内容string)将始终保持不变(不使用包unsafe)。

如果要同时访问string多个goroutine中的类型变量,并且至少其中一次访问是写操作(更改变量值的写操作),则需要进行同步string。对于Go中任何类型的变量都是如此,该string类型在任何方面都不是特殊的。

实际上这是什么意思?

如果您有一个接收string值的函数,"hello"则可以确保该string值将保持"hello"不变。因此,如果您自己不更改参数(例如,不给它分配新值),它将始终保留该string"hello"

作为反例,如果您的函数收到slice值[]byte{1, 2, 3},则您没有相同的保证,因为slice是可变的。调用方还具有切片值(slice标头),否则它不能首先传递它。而且如果调用者同时修改了slice 的
元素 ,因为它们共享相同的后备数组,则传递给您的slice还将看到更改的数据……具有适当的同步;因为如果没有同步,这将是数据争用(因此是未定义的行为)。

请参阅以下示例:

var sig = make(chan int)

func main() {
    s := []byte{1, 2, 3}
    go func() {
        <-sig
        s[0] = 100
        sig <- 0
    }()
    sliceTest(s)
}

func sliceTest(s []byte) {
    fmt.Println("First  s =", s)

    sig <- 0 // send signal to modify now
    <-sig    // Wait for modification to complete

    fmt.Println("Second s =", s)
}

输出(在Go Playground上尝试):

First  s = [1 2 3]
Second s = [100 2 3]

专注于sliceTest():它接收到一片,然后打印出来。然后稍等(对并发的goroutine进行“修改”,然后等待此修改完成),然后再次打印它,并且它已更改,但sliceTest()它本身并未对其进行修改。

现在,如果sliceTest()string改为接收一个参数,则不会发生这种情况。



 类似资料:
  • 问题内容: 有人告诉我不能更改Java中的字符串。下面的代码呢? 它不改变字符串吗?另外,replace()的实现在哪里;相比于(); 等于(); 提供?我只是在这里使用这些功能,但实际上在哪里实现? 问题答案: String.replace()返回一个新的String。 “名称”是对String对象的引用,因此可以将其重新分配为指向name.replace(),但它将指向一个新对象。 这是Str

  • 问题内容: 考虑以下示例。 现在,在Java中,String对象是不可变的。然后如何为对象分配值“帮助!”。这是否与Java中字符串的不变性相矛盾?有人可以向我解释不变性的确切概念吗? 编辑: 好。我现在明白了,但只是一个后续问题。那么下面的代码呢: 这是否意味着将再次创建两个对象(“密西西比”和“ M!ss!ss!pp!”),并且引用在方法之后指向另一个对象? 问题答案: 不是对象,而是对对象的

  • 问题内容: 我知道问题的标题不是很清楚,对此感到抱歉,不知道如何提出。我有一个非常基本的Java实现问题,我想着重于应用程序性能,但是它也涉及Java中的String创建模式。 我了解Java中字符串的不变性概念。我不确定的是,我在某处读到以下内容不会创建两个不同的String对象: 我想知道Java是怎么做到的?它实际上是否在程序存储器中寻找一个String值并检查其是否存在,如果不存在则创建一

  • 据我所知, 可变字符串可以更改,不可变字符串不能更改。 这里我想这样改变字符串的值, 另一种方法是, 在这两种情况下,我都试图改变str的值。谁能告诉我,这两种情况的区别是什么,让我清楚地了解可变和不可变对象。

  • 问题内容: 在Go 规范中写道: 字符串是不可变的:一旦创建,就无法更改字符串的内容。 我有以下代码: 我原本希望地址在之后更改。就像Java那样,我们在其中重新分配String引用。 什么是“不变性”? 问题答案: 值 是不可变的。 不是一个值。这是一个 变量 (类型)。并且变量的值可能会更改,这就是您对任何编程语言所期望的。 是一个值,这是不可变的。是另一个值,当您分配给时,您只需为变量分配另

  • 本文向大家介绍Java中的不可变字符串,包括了Java中的不可变字符串的使用技巧和注意事项,需要的朋友参考一下 在Java中,不可变对象是指那些不能更改或修改(一旦修改)数据的对象。字符串类是不可变的,即一旦我们创建了一个字符串对象,就无法修改其数据。