面试时被问到了,补下
import java.util.concurrent.atomic.AtomicInteger; /** * Created by tzq on 2018/7/15. */ public class TestAtomic { /** * @param java中的原子操作类AtomicInteger * @author yangcq * * 关于AtomicInteger的说明(来自官方文档注解) * /** * An {@code int} value that may be updated atomically. See the * {@link java.util.concurrent.atomic} package specification for * description of the properties of atomic variables. An * {@code AtomicInteger} is used in applications such as atomically * incremented counters, and cannot be used as a replacement for an * {@link java.lang.Integer}. However, this class does extend * {@code Number} to allow uniform access by tools and utilities that * deal with numerically-based classes. * * @since 1.5 * @author Doug Lea */ public static void main(String[] args) { // 初始值为1 AtomicInteger atomicInteger = new AtomicInteger(1); System.out.println("--初始值atomicInteger = " + atomicInteger); // 以原子方式将当前值加1,注意这里返回的是自增前的值 System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.getAndIncrement()); System.out.println("--自增后的 atomicInteger = " + atomicInteger); // 以原子方式将当前值减1,注意这里返回的是自减前的值 System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.decrementAndGet()); System.out.println("--自减后的 atomicInteger = " + atomicInteger); // 以原子方式将当前值与括号中的值相加,并返回结果 System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.addAndGet(11)); System.out.println("--自增后的 atomicInteger = " + atomicInteger); // 如果输入的值等于预期的值,则以原子方式将该值设置成括号中的值 //atomicInteger等于第一个参数返回true 并将第二个参数赋值 System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.compareAndSet(12, 2)); System.out.println("--自减后的 atomicInteger = " + atomicInteger); System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.compareAndSet(10, 9999)); System.out.println("--自减后的 atomicInteger = " + atomicInteger); /** * 一,AtomicInteger 是如何实现原子操作的呢? * * 我们先来看一下getAndIncrement的源代码: * public final int getAndIncrement() { * for (;;) { * int current = get(); // 取得AtomicInteger里存储的数值 * int next = current + 1; // 加1 * if (compareAndSet(current, next)) // 调用compareAndSet执行原子更新操作 * return current; * } * } * * 这段代码写的很巧妙: * 1,compareAndSet方法首先判断当前值是否等于current; * 2,如果当前值 = current ,说明AtomicInteger的值没有被其他线程修改; * 3,如果当前值 != current,说明AtomicInteger的值被其他线程修改了,这时会再次进入循环重新比较; * * 注意这里的compareAndSet方法,源代码如下: * public final boolean compareAndSet(int expect, int update) { * return unsafe.compareAndSwapInt(this, valueOffset, expect, update); * } * * 调用Unsafe来实现 * private static final Unsafe unsafe = Unsafe.getUnsafe(); * * 二,java提供的原子操作可以原子更新的基本类型有以下三个: * * 1,AtomicBoolean * 2,AtomicInteger * 3,AtomicLong * * 三,java提供的原子操作,还可以原子更新以下类型的值: * * 1,原子更新数组,Atomic包提供了以下几个类:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray * 2,原子更新引用类型,也就是更新实体类的值,比如AtomicReference<User> * AtomicReference:原子更新引用类型的值 * AtomicReferenceFieldUpdater:原子更新引用类型里的字段 * AtomicMarkableReference:原子更新带有标记位的引用类型 * 3,原子更新字段值 * AtomicIntegerFieldUpdater:原子更新整形的字段的更新器 * AtomicLongFieldUpdater:原子更新长整形的字段的更新器 * AtomicStampedReference:原子更新带有版本号的引用类型的更新器 * * */ } }
四,AtomicIntegerFieldUpdater:原子更新整形的字段的更新器
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; /** * Created by tzq on 2018/7/16. */ public class Test_AtomicIntegerFieldUpdater { /** * @param AtomicIntegerFieldUpdater:原子更新整形的字段的更新器 * @author yangcq */ // 创建原子更新器,并设置需要更新的对象类和对象的属性 private static AtomicIntegerFieldUpdater<User> atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(User.class, "age1"); public static void main(String[] args) { // 设置age的初始值为1000 User user = new User(); user.setUserName("yangcq"); user.setAge(1000); user.setAge1(500); // 原子更新引用数据类型的字段值 System.out.println(atomicIntegerFieldUpdater.getAndIncrement(user)); // 更新以后的值 System.out.println(atomicIntegerFieldUpdater.get(user)); System.out.println(user.getAge()); System.out.println(user.getAge1()); } //实体类User public static class User{ private String userName; public volatile int age; public volatile int age1; // setter、getter方法 public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getAge1() { return age1; } public void setAge1(int age1) { this.age1 = age1; } } }