JAVA并发编程之-原子变量

做者:毕来生
微信:878799579

一、什么是原子变量?

​ 原子变量保证了该变量的全部操做都是原子的,不会由于多线程的同时访问而致使脏数据的读取问题。java

二、经过synchronized保证原子操做
  1. 获取锁对象
  2. 获取失败/获取不到 ->阻塞队列等待
  3. 释放锁对象
三、Atomic之AtomicInteger源码分析

java.util.concurrent.atomic包下帮助咱们提供了不少原子性的支持,请参考下图微信

在这里插入图片描述

  • AtomicInteger和AtomicIntegerArray:基于Integer类型
  • AtomicBoolean:基于Boolean类型
  • AtomicLong和AtomicLongArray:基于Long类型
  • AtomicReference和AtomicReferenceArray:基于引用类型多线程


    构造方法以下并发

private volatile int value;

  /**
   * Creates a new AtomicInteger with the given initial value.
   *
   * @param initialValue the initial value
   */
  public AtomicInteger(int initialValue) {
      value = initialValue;
  }

  /**
   * Creates a new AtomicInteger with initial value {@code 0}.
   */
  public AtomicInteger() {
  }

若是经过构造方法设置原子变量。如不设置初始值则会默认初始化为0。ide

如下为方法为AtomicInteger基于原子操做经常使用方法源码分析

//获取当前原子变量中的值并为其设置新值
public final int getAndSet(int newValue)

//比较当前的value是否等于expect,若是是设置为update并返回true,不然返回false
public final boolean compareAndSet(int expect, int update)

//获取当前的value值并自增一
public final int getAndIncrement()

//获取当前的value值并自减一
public final int getAndDecrement()

//获取当前的value值并为value加上delta
public final int getAndAdd(int delta)
四、实战演练

在多线程下。我但愿对num = 0;进行自增,10个线程,每一个线程对变量自增10000次。结果应该是100000才对。atom

首先咱们先来一个错误示范:spa

package org.bilaisheng.juc;

/**
 * @Author: bilaisheng
 * @Wechat: 878799579
 * @Date: 2019/1/1 21:58
 * @Todo: AtomicInteger 原子性错误示范。仅演示使用
 * @Version : JDK11 , IDEA2018
 */
public class AtomicIntegerErrorTest {

    // 举例10条线程并发,实际条数请参考本身场景
    private static final int THREAD_COUNT = 10;

    private static int num = 0;

    public static void main(String[] args) {

        Thread[] threads = new Thread[THREAD_COUNT];

        for (int i = 0; i < THREAD_COUNT; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    // 此处设置10000.过小看不到效果。请酌情设置
                    for (int j = 1; j <=10000 ; j++) {
                        // 如想要看到结果请放开下行注释
                        //System.out.println(Thread.currentThread().getName() +" num = "+num);
                        num++ ;
                    }
                }
            });
            threads[i].start();
        }

        System.out.println(Thread.currentThread().getName());
        System.out.println(Thread.activeCount());

        while (Thread.activeCount()>2){
            Thread.yield();
        }

        System.out.println(num);
    }

}

运行结果举例两张以下图所示。每次运行结果都不相同线程

在这里插入图片描述

在这里插入图片描述

接下来咱们的AtomicInteger就该登场了3d

package org.bilaisheng.juc;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: bilaisheng
 * @Wechat: 878799579
 * @Date: 2019/1/1 23:02
 * @Todo:
 * @Version : JDK11 , IDEA2018
 */
public class AtomicIntegerTest {


    private static final int THREADS_CONUT = 10;
    public static AtomicInteger num = new AtomicInteger(0);


    public static void main(String[] args) {
        Thread[] threads = new Thread[THREADS_CONUT];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    // 此处设置10000.过小看不到效果。请酌情设置
                    for (int j = 1; j <=10000 ; j++) {
                        // 如想要看到结果请放开下行注释
                        //System.out.println(Thread.currentThread().getName() +" num = "+num);
                        num.incrementAndGet();
                    }
                }
            });
            threads[i].start();
        }

        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
        System.out.println(num);
    }
}

结果是无论怎么运行结果都和预期下相同。运行结果以下图:

在这里插入图片描述

五、 Volatile能够保证变量原子性吗?

​ 咱们先来看一下下面两行代码

private volatile long num = 4642761357212574643L;

private volatile double amt= 4642761357212574643.23165421354;

如上代码并不能保证num以及amt两个变量就是原子性的,在32位处理器中 哪怕是经过volatile关键字进行修饰也没法保证变量原子性。由于在32位系统下。若是出现了多线程同时操做某个变量。这个变量正在被线程a进行修改。此时线程b访问此变量。可能只获取到该变量的前32位,故可能会致使原子性失效。致使不可预知的状况以及错误。若是本地和生产均为64位处理器。请忽略以上废话。

喜欢就关注我吧

在这里插入图片描述

相关文章
相关标签/搜索