谈谈线程安全

谈谈线程安全

线程安全问题是由于多个线程同时执行写操作引起的,例如多个线程同时对一个变量进行+1操作,伪代码如下。

int count  = 1;
Function A(){
    count = count + 1;
}
//thread1开始执行A()
//thread2开始执行A()
//thread3开始执行A()
......

//threadn开始执行A()

我们再来看看count=count+1的汇编代码,如下:

mov eax,[count的内存地址]  //将count值放入寄存器eax中
add eax,1                //对eax加1
mov [count的内存地址],eax  //将eax寄存器中的值放入count的地址中
  • 从上述代码中可以看出,我们对count 执行加一的操作需要三步,①取出count值。②将count加一。③将count写回内存。当有多个线程同时对count进行操作时,可能会发生什么情况?
  • 有可能,线程1刚把count取出来,恰巧线程2也把count取出来了,两个线程都执行加一操作,两个线程的count值就都变成了2,最后,线程1和线程2写回的count值都是2,但是我们想要的结果是3。这就造成了线程不安全的问题。

如何解决线程不安全的问题呢?

有两种解决方案:

  • 第一种,在线程1读取count值、count+1、写回count值的过程中,线程2必须等待,直到线程1结束。
  • 第二种,线程1、2可以同时读取count值,同时给count+1,但是写回的时候,线程1、2要竞争系统锁,如果线程1竞争到了,线程1要判断现在内存中的count值(1)是否与之前读到的count值(1)相同,如果一致则写回,然后释放锁;线程2发现内存中的count值变成了2,与之前读到的1不一致,需要重复加载count,计算、加锁比较,直到成功。

本文中的例子,参考《深入理解Java高并发编程》P59

Original: https://www.cnblogs.com/classicltl/p/16416761.html
Author: classic123
Title: 谈谈线程安全

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/710979/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球