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周的时间,并在第四周时从理论上解释通了这个原因。

目录
相关文章
|
2月前
|
缓存 安全 Java
为什么全局变量可能成为多线程环境中的安全隐患
为什么全局变量可能成为多线程环境中的安全隐患
|
2月前
|
安全 Java 开发者
丢失的8小时去哪里了?SimpleDateFormat线程不安全,多线程初始化异常解决方案
丢失的8小时去哪里了?SimpleDateFormat线程不安全,多线程初始化异常解决方案
57 0
|
1月前
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
46 1
|
2月前
|
安全
python_threading多线程、queue安全队列
python_threading多线程、queue安全队列
39 2
|
2月前
|
缓存 安全 Java
7张图带你轻松理解Java 线程安全,java缓存机制面试
7张图带你轻松理解Java 线程安全,java缓存机制面试
|
2天前
|
缓存 安全 Java
为什么手动创建的线程池比使用Executors类提供的线程池更安全
为什么手动创建的线程池比使用Executors类提供的线程池更安全
|
16天前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
24 0
|
16天前
|
安全 Java 调度
Java面试题:Java内存优化、多线程安全与并发框架实战,如何在Java应用中实现内存优化?在多线程环境下,如何保证数据的线程安全?使用Java并发工具包中的哪些工具可以帮助解决并发问题?
Java面试题:Java内存优化、多线程安全与并发框架实战,如何在Java应用中实现内存优化?在多线程环境下,如何保证数据的线程安全?使用Java并发工具包中的哪些工具可以帮助解决并发问题?
18 0
|
22天前
|
Java Redis 数据安全/隐私保护
Redis14----Redis的java客户端-jedis的连接池,jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,最好用jedis连接池代替jedis,配置端口,密码
Redis14----Redis的java客户端-jedis的连接池,jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,最好用jedis连接池代替jedis,配置端口,密码
|
22天前
|
安全 NoSQL Java
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R