文章目录
  1. 1. 文档更新说明
  2. 2. 前言
  3. 3. 数据竞争
  4. 4. 解决数据竞争的方法
  5. 5. 例子

文档更新说明

  • 最后更新 2019年01月25日
  • 首次更新 2019年01月25日

前言

  简述并发时, 对公共数据的访问出现的数据竞争问题和解决思路.

数据竞争

  当同一时间有多个线程(或者goroutine)去读取同一块数据(变量), 因为没有涉及到写入操作, 所以是并发安全的. 但是如果其中有一个线程有写入操作(正常都是有写入操作的), 那么就一定会出现数据竞争问题, 即两个线程同时读取数据之后, 又同时写入数据, 这个时候肯定有一个线程写入的数据会丢失.举个例子

1
2
3
i := 0
i = i + 5 //线程A
i = i + 10 //线程B

那么结果i最终可能是15, 也可能是5或者10

解决数据竞争的方法

  1. 不要写变量, 设计成只读操作. 也就是一开始把数据都生成好了, 以后只读就可以啦. (这个太天真了, 数据一般都是有更新操作的)
  2. 让变量只被一个线程访问. 也就是说存在一个线程专门(monitor)用来更新变量, 其他线程需要更新变量的时候, 则向这个线程发个消息,由monitor负责更新即可.
  3. 串行绑定. 这个比较难理解, 就是一个变量可以在多个线程里存在, 但是却是按照顺序, 先进入线程1, 再进入线程2
  4. 互斥访问. 这个比较常见了, 一个线程访问公共变量的时候加一个锁, 访问结束再释放锁. 这样就确保了同一时间内只有一个线程能访问到.

例子

  上述几种方法, 都可以在<Go语言圣经>第9章第1节中找到详细例子

文章目录
  1. 1. 文档更新说明
  2. 2. 前言
  3. 3. 数据竞争
  4. 4. 解决数据竞争的方法
  5. 5. 例子