zoukankan      html  css  js  c++  java
  • i++的原子性问题

    一、什么是原子性

      简单的可以理解为:操作是不可再分割的,比如;

    int i=0;

    但是i++的操作是可以再分的,比如:

    i++ 
    //分解后
    i=i+i

    上面的代码在多线程环境下取值是有问题的,比如:

    package com.example.demo.juc;
    
    /**
     * @author DUCHONG
     * @since 2019-01-07 19:11
     **/
    public class AtomicTest {
    
        public static void main(String[] args) {
    
            AtomicThread atomicTest=new AtomicThread();
            for (int i=1;i<=20;i++){
    
                new Thread(atomicTest).start();
            }
        }
    }
    
    class AtomicThread implements Runnable {
    
        private  int num=1;
        @Override
        public void run() {
            try {
                Thread.sleep(300);
                System.out.println(getNum());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public int getNum(){
            return num++;
        }
    }

    结果:

    这种问题当然可以通过加synchronized 关键字来解决,那有没有另外一种方案呢,答案肯定是有的,且在jdk1.5的时候就有了,那就是Atomic包下的原子类

    优化后:

    package com.example.demo.juc;
    
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * @author DUCHONG
     * @since 2019-01-07 19:11
     **/
    public class AtomicTest {
    
        public static void main(String[] args) {
    
            AtomicThread atomicTest=new AtomicThread();
            for (int i=1;i<=20;i++){
    
                new Thread(atomicTest).start();
            }
        }
    }
    
    class AtomicThread implements Runnable {
    
        private AtomicInteger at=new AtomicInteger(1);
        @Override
        public void run() {
            try {
                Thread.sleep(300);
                System.out.println(getNum());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public int getNum(){
            return at.getAndIncrement();
        }
    }

    看源码:

    构造函数中的值,是volatile类型的

    自增或者自减时,使用了CAS算法,CAS算法有三个操作数:

    内存值:A

    预估值:B

    新值:V 

    当且仅当 A=B 是 A=V 

    否则不做任何操作。

  • 相关阅读:
    poj 3071 Football (概率dp)
    CF1408G Clusterization Counting
    2-sat
    线段树优化建图
    SP5971 LCMSUM
    [NOI2020]命运
    SP19149 INS14H
    Atcoder ARC-068
    CF908G New Year and Original Order
    (四)、Fiddler打断点
  • 原文地址:https://www.cnblogs.com/geekdc/p/10235283.html
Copyright © 2011-2022 走看看