zoukankan      html  css  js  c++  java
  • java并发编程学习笔记(一)初识并发原子性

    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个线程同时都可读写,可使用->修改为以下状态

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

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

                

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

                 

  • 相关阅读:
    pygame 笔记-7 生命值/血条处理
    pygame 笔记-6 碰撞检测
    pygame 笔记-5 模块化&加入敌人
    pygame 笔记-4 代码封装&发射子弹
    tk.mybatis通用插件updateByPrimaryKeySelective无法自动更新ON UPDATE CURRENT_TIMESTAMP列的解决办法
    pygame 笔记-3 角色动画及背景的使用
    pygame 笔记-2 模仿超级玛丽的弹跳
    pygame 笔记-1 按键控制方块移动
    mysql技巧:如果记录存在则更新/如果不存在则插入的三种处理方法
    mac上mysql8.0以tar.gz方式手动安装
  • 原文地址:https://www.cnblogs.com/LingoXu/p/5252146.html
Copyright © 2011-2022 走看看