JAVASE_JUC-原子类AtomicXXXX详解

1.原子性介绍

        原子性:操作过程中不允许其他线程干扰, 可以理解为数据操作是整体,整体只有成功或失败,不允许出现部分成功部分失败,而AtomicXXX原子类本身就具有原子性。

例如:

        num++在多线程下执行是不安全的, num++可以分解为

        1. 读取num的值(从主内存读取)

        2. 对num+1(副本内存操作)

        3. 把结果赋值给num(更新主内存)

        所以说num++是不具备原子性的

        如果希望num++具备原子性,可以把num++的三个步骤看做一个不可拆分的整体。

        只要具备了原子性,就一定是线程安全的,可以保证数据结果的准确.

2.JUC中的原子类

 3.使用AtomicInteger类保证线程安全

        3.1原始方式-使用synchronized同步锁解决线程安全

package com.bjsxt.test2;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo1 {
    private static int a = 0;
    public static void main(String[] args) {
        //创建固定线程线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        //新建五个任务
        for (int i = 0; i < 5; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    synchronized ("锁"){
                        //给可能会出现线程安全的代码上锁
                        test();
                    }
                }
            });
        }
        //关闭线程池
        executorService.shutdown();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(a);
    }
    public static void test(){
        //创建可能会出现线程安全问题的代码
        for (int i = 0; i < 1000; i++) {
            a++;
        }
    }
}

        结果: 5000 

         3.2使用原子类方式-AtomicInteger方式解决

package com.bjsxt.test2;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Demo2 {
    public static void main(String[] args) {
        //实例化原子类
        AtomicInteger atomicInteger = new AtomicInteger(0);
        //创建固定线程线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        //创建五个任务
        for (int i = 0; i < 5; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    for (int n = 0; n < 1000; n++) {
                        //自增一方法
                        atomicInteger.incrementAndGet();
                    }
                }
            });
        }
        executorService.shutdown();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(atomicInteger.get());

    }
}

结果: 5000 

         3.3原子类中的方法介绍

public class Test3 {
  public static void main(String[] args) {
    AtomicInteger atomicInteger = new AtomicInteger(0);

    //先获取atomicInteger中的值, 再将值+1   num++
    int i = atomicInteger.getAndIncrement();
    System.out.println(i); //0

    //先将值+1, 先获取atomicInteger中的值 ++num
    int i2 = atomicInteger.incrementAndGet();
    System.out.println(i2); //2

    //先获取atomicInteger中的值, 再将值-1   num--
    int i3 = atomicInteger.getAndDecrement();
    System.out.println(i3); //2

    //先将值-1, 先获取atomicInteger中的值 --num
    int i4 = atomicInteger.decrementAndGet();
    System.out.println(i4); //0

    //先获取atomicInteger中的值, 再+指定的值
    int i5 = atomicInteger.getAndAdd(10);
    System.out.println(i5); //0

    先+指定的值, 先获取atomicInteger中的值
    int i6 = atomicInteger.addAndGet(20);
    System.out.println(i6); //30

    int i7 = atomicInteger.getAndAdd(-5);
    System.out.println(i7); //30

    int i8 = atomicInteger.addAndGet(-10);
    System.out.println(i8); //15

    //改变atomicInteger中的值
    atomicInteger.set(100);

    int andSet = atomicInteger.getAndSet(200);
    System.out.println(andSet); //100

    //先获取atomicInteger中的值
    int i1 = atomicInteger.get();
    System.out.println(i1); //200
  }
}

        3.4AtomicInteger底层实现原理

         原子类AtomicInteger底层使用的是volatile 和 CAS 实现。

注意:

         * AtomicInteger: 天生就是线程安全的  在使用原子类的时候  不许要额外加锁
         * 除非操作的不是原子类 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值