String copy on write 引发的线程不安全

简介: <br><br>    一个string对象的读操作是线程安全的么?答案是否定的。读取一个string在某些情况下是线程不安全的。这是为什么呢?原因就是string在优化存储空间时采用的策略cow。<br><br><br> 什么是cow<br><p>     Cow 是copy on write的缩写。String 为了减少内存拷贝,当两个string对象的内容相同时,他们指向同一块内


   一个string对象的读操作是线程安全的么?答案是否定的。读取一个string在某些情况下是线程不安全的。这是为什么呢?原因就是string在优化存储空间时采用的策略cow。


什么是cow

     Cow 是copy on write的缩写。String 为了减少内存拷贝,当两个string对象的内容相同时,他们指向同一块内存空间,并通过引用计数来表示有多少对象引用了这块内存。当其中某个string对象的内容发生改变时,string会先重新分配一块空间,把原来的内容拷贝到新空间,原来的空间的引用计数减去1。


什么情况下引发cow

      当程序判断string对象要改变时,就会引发cow。一种比较少见的情况就是,程序获得了string对象的非const引用,那么程序无法判断在接下来的操作中是否会改变这个string对象。所以会触发cow操作。一个典型的例子是string::operator[], 当一个非const对象调用[]操作符时,实际上获得的是对象的非const引用,于是引发了cow。


危害
      上边的operator[],如果只是为了读取字符串的话,那么我们期望这个操作应该是线程安全的。但实际上这个读操作包含了写操作,假如另一个线程同时在读这个字符串的话,程序就有可能在这里使内存写坏。为了解决这个问题,必须给string对象限定为const.


我在产品中发现了这个问题,为了调查这个问题花费了3周的时间,并在第四周时从理论上解释通了这个原因。

目录
相关文章
|
5月前
|
缓存 安全 Java
为什么全局变量可能成为多线程环境中的安全隐患
为什么全局变量可能成为多线程环境中的安全隐患
|
4月前
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
577 1
|
5月前
|
安全
python_threading多线程、queue安全队列
python_threading多线程、queue安全队列
48 2
|
5月前
|
缓存 安全 Java
7张图带你轻松理解Java 线程安全,java缓存机制面试
7张图带你轻松理解Java 线程安全,java缓存机制面试
|
2月前
|
Java
【Java集合类面试十二】、HashMap为什么线程不安全?
HashMap在并发环境下执行put操作可能导致循环链表的形成,进而引起死循环,因而它是线程不安全的。
|
2月前
|
安全 算法 Java
【Java集合类面试二】、 Java中的容器,线程安全和线程不安全的分别有哪些?
这篇文章讨论了Java集合类的线程安全性,列举了线程不安全的集合类(如HashSet、ArrayList、HashMap)和线程安全的集合类(如Vector、Hashtable),同时介绍了Java 5之后提供的java.util.concurrent包中的高效并发集合类,如ConcurrentHashMap和CopyOnWriteArrayList。
【Java集合类面试二】、 Java中的容器,线程安全和线程不安全的分别有哪些?
|
2月前
|
存储 安全 Go
Go 面试题:string 是线程安全的吗?
Go 面试题:string 是线程安全的吗?
|
2月前
|
存储 安全 Java
解锁Java并发编程奥秘:深入剖析Synchronized关键字的同步机制与实现原理,让多线程安全如磐石般稳固!
【8月更文挑战第4天】Java并发编程中,Synchronized关键字是确保多线程环境下数据一致性与线程安全的基础机制。它可通过修饰实例方法、静态方法或代码块来控制对共享资源的独占访问。Synchronized基于Java对象头中的监视器锁实现,通过MonitorEnter/MonitorExit指令管理锁的获取与释放。示例展示了如何使用Synchronized修饰方法以实现线程间的同步,避免数据竞争。掌握其原理对编写高效安全的多线程程序极为关键。
53 1
|
3月前
|
缓存 安全 Java
多线程线程池问题之为什么手动创建的线程池比使用Executors类提供的线程池更安全
多线程线程池问题之为什么手动创建的线程池比使用Executors类提供的线程池更安全
|
3月前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
45 0