java中原子类操作


1.概述

  • 包: java.util.concurrent.atomic
  • 特点: 它提供的方法都是原子性操作,在多线程情况下不会出现线程安全问题

2.分类

  1. 原子更新基本类型

    如:

    • AtomicBoolean 对boolean类型变量实现原子操作
    • AtomicInteger 对int/Integer类型变量实现原子操作
  2. 原子更新数组

    如:

    • AtomicIntegerArray 对数组实现原子操作
    • AtomicIntegerLongArray
  3. 原子更新抽象类

    如:

    • AtomicReference 对引用类型变量实现原子性操作
  4. 原子类更新字段

    如:

    • AtomicIntegerFieldUpdater 对对象中的int类型变量实现原子性操作

3.实现原理

    public final int incrementAndGet() {
        for (;;) {
            int current = get();    //第一步
            int next = current + 1;    //第二步
            if (compareAndSet(current, next))    //第三步
                return next;
        }
    }
  • 逻辑分析

    • 第一步获取当前的value值current
    • 第二步对current进行加一操作获得next
    • 第三步为关键步骤,通过对当前值current与next比较,如果符合预期(即只增加了1),则说明没有被其他线程修改过,此时compareAndSet返回true,否则继续循环尝试更新.

4.简单实例

4.1简单类型

//获取自增值的类
class Increase{
    //public Integer i = 0; //不使用原子类,赋初始值为0
    public AtomicInteger i = new AtomicInteger(0);  //使用原子类,赋初始值为0
    public Integer getIncrease(){
        //return i++;   //非原子性操作,多线程情况下会出现线程安全问题
        return i.getAndIncrement(); //原子性操作,不会出现线程安全问题
    }
}

//测试类
public class AtomicTest {
    public static void main(String[] args){
        Increase inc = new Increase();
        //线程1
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("result1: "+inc.getIncrease());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        //线程2
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("result2: "+inc.getIncrease());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

4.2.原子类更新字段

  • 对象所属类
public class User {
    public volatile int age;    //必须使用volatile关键字
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
  • 测试类
public class AtomicTest {
    public static void main(String[] args){
        AtomicIntegerFieldUpdater<User> field = AtomicIntegerFieldUpdater.newUpdater(User.class,"age");
        User user = new User();
        user.setAge(0);
        field.getAndIncrement(user);    //更新age值(自增1),此操作为原子操作
        System.out.println(user.age);   //输出age值为1
    }
}

文章作者: Bryson
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Bryson !
评论
 上一篇
下一篇 
java中锁的种类--重入锁丶自旋锁 java中锁的种类--重入锁丶自旋锁
1.重入锁 重入锁又名递归锁,当同一个线程在外层方法已经获取锁的时候,再进入内层方法时会自动获取该锁 优点: 可以一定程度避免死锁 java中的ReentrantLock与Synchronized都是重入锁 简单认知public
2018-05-20
  目录