本文作者:黄海燕,叩丁狼高级讲师。原创文章,转载请注明出处。
前言
线程并发问题一直都是面试的时候经常问的问题,为什么那些面试官、老总喜欢问这些问题呢,因为多线程运行起来要比快呀?那多线程就真的要比单线程快?在我看来未必,因为多线程存在上下文切换[1]、线程死锁、以及一些受限于硬件的问题。所以今天我们就面试当中的一些问题,一起来学习并解决线程并发问题。
自增自减原子性问题
曾经我遇到过这样的一个问题[在我刚刚毕业出来面试的时候,曾经遇到过这样的问题,你觉得在多线程的情况下i++数据安全么?我当时是这样想的,你问我肯定是需要问为什么的,如果我说安全那就没什么必要说为什么了,所以我当时的回答是不安全的,但是为什么我就回答出来了,所以回家后我就立志要这个问什么弄明白。]:你觉得在多线程的情况下i++数据安全么?
答案是不安全的。
现在我们一起来分析一下为什么?
首先i++;它本身不仅仅是表面上看上去只有一个操作,实际上它是一个“读取 - 修改 - 写入”的操作,i++可以看做一下三步操作:
- 先是将i的值从内存中拿出来;
- 然后将i的值加1;
- 最后将加1后的值存放到i的内存中;
所以i++存在原子性问题[2]。
解决方案有两个:
- 方案1:使用synchronized加锁,使i的数据同步,但是这个方式简单是简单,比较耗资源,在多线程竞争资源的时候,加锁、释放锁,线程之间不停的切换会引起性能问题。一个线程持有锁,其它线程需要等到的这把锁之后才能执行,期间线程是被挂起,容易导致死锁发生。
- 方案2