首页 > 技术文章 > java并发编程学习笔记(一)初识并发原子性

LingoXu 2016-03-07 22:09 原文

1、并发的意义

    现在是一个多核的时代,并发的存在意义就是为了能够充分利用多核计算机的优势,提高程序的运行效率;

2、并发的风险

    竞争-----多个线程对内存数据数据进行读写操作时,对数据处理结果的一个竞争。(笔者是这么认为的)

    使用以下的例子来说明并发的风险:由于该方法中的value++操作不是原子性的,是分为读->运算->赋值 这3个步骤的。

    假如线程A执行了读,正准备开始运算的时候,线程B开始调用这个实例的getNext方法,那么这个时候线程B读取的数据与线程A读取的数据是一样的。

     即A获得的结果是value=value+1;线程B运算也是value=value+1;然而线程B在线程A之后才调用这个方法,按照假设,线程B应该返回value+2才对。

    ps:文字描述的value就是初始值。

    

public class  demo {

 private int value;

  public int getNext(){
    return value++;
  }
}

 3、上述问题产生的原因有2个:

        1 线程共享内存的地址空间(即内存数据对2个线程都可见)

        2 getNext方法并不是原子性的(内部代码执行是可分割的)

        这样就容易产生 竞争条件。

      总结:线程共享相同的内存地址空间,可以访问或修改其他线程正在使用的变量。这对于线程间的通信,是十分方便的。但是其中存在着数据意外变更的风险,因此访问共享的内存变量时,线程需要经过合理的调度,才能保证程序的正常运行。

4、要纠正上述问题,可以从2个方面着手,现在先从第二个原因来着手解决。(非原子化操作)

    目标1:将value++的操作原子化。

            使用原子类AutomicInterger  来代替 int类型 

            自增操作就可以写为value.incrementAndGet();

    这样一来,线程对数据的操作就是原子化的,不会出现竞争条件。

   目标2:内存数据对2个线程同时都可读写,可使用->修改为以下状态

             状态一:只对单个线程可读写(某个线程正在使用该对象时,另一个线程无法获取并使用该对象,另一个线程进入阻塞状态)

             状态二:两个线程都可读,但是只对一个线程开放数据修改权限

            

            以上两个状态:需要使用到锁,在下一节中做详细介绍。

 

             

推荐阅读