《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
Unsafe
的源码如下:
/**
-
如果当前数值是expected,则原子的将Java变量更新成x
-
@return 如果更新成功则返回true
*/
public final native boolean compareAndSwapObject(Object o,
long offset,
Object expected,
Object x);
public final native boolean compareAndSwapInt(Object o, long offset,
int expected,
int x);
public final native boolean compareAndSwapLong(Object o, long offset,
long expected,
long x);
通过代码,我们发现Unsafe只提供了3种CAS方法:compareAndSwapObject
、compareAndSwapInt
和compareAndSwapLong
。
再看AtomicBoolean源码,发现它是先把Boolean转换成整型,再使用compareAndSwapInt进行CAS,所以原子更新char、float和double变量也可以用类似的思路来实现。
通过原子的方式更新数组里的某个元素,Atomic
包提供了以下4个类:
-
AtomicIntegerArray:原子更新整型数组里的元素。
-
AtomicLongArray:原子更新长整型数组里的元素。
-
AtomicReferenceArray:原子更新引用类型数组里的元素。
AtomicIntegerArray类主要是提供原子的方式更新数组里的整型,其常用方法如下。
-
int addAndGet(int i,int delta)
:以原子方式将输入值与数组中索引i的元素相加。 -
boolean compareAndSet(int i,int expect,int update)
:如果当前值等于预期值,则以原子方式将数组位置i的元素设置成update值。
以上几个类提供的方法几乎一样,所以本节仅以AtomicIntegerArray
为例进行讲解。
AtomicIntegerArray
的使用实例代码:
/**
-
@author xppll
-
@date 2022/1/14 18:22
*/
public class AtomicIntegerArrayTest {
static int[] value = new int[]{1, 2};
static AtomicIntegerArray ai = new AtomicIntegerArray(value);
public static void main(String[] args) {
ai.getAndSet(0, 3);
System.out.println(ai.get(0));//3
System.out.println(value[0]);//1
}
}
需要注意的是,数组value通过构造方法传递进去,然后AtomicIntegerArray会将当前数组复制一份,所以当AtomicIntegerArray对内部的数组元素进行修改时,不会影响传入的数组
原子更新基本类型的AtomicInteger,只能更新一个变量,如果要原子更新多个变量,就需要使用这个原子更新引用类型提供的类。Atomic
包提供了以下3个类:
-
AtomicReference:原子更新引用类型。
-
AtomicReferenceFieldUpdater:原子更新引用类型里的字段。
-
AtomicMarkableReference:原子更新带有标记位的引用类型。可以原子更新一个布尔类型的标记位和引用类型。构造方法是AtomicMarkableReference(V initialRef,boolean initialMark)。
以上几个类提供的方法几乎一样,所以本节仅以AtomicReference为例进行讲解。
AtomicReference
的使用示例代码:
/**
-
@author xppll
-
@date 2022/1/14 17:23
*/
public class AtomicReferenceTest {
public static AtomicReference atomicReference = new AtomicReference();
public static void main(String[] args) {
User user = new User(“xpp”, 20);
atomicReference.set(user);
User updateUser = new User(“updateXpp”, 24);
atomicReference.compareAndSet(user, updateUser);
System.out.println(atomicReference.get().getName());//updateXpp
System.out.println(atomicReference.get().getOld());//24
}
static class User {
private String name;
private int old;
public User(String name, int old) {
this.name = name;
this.old = old;
}
public String getName() {
return name;
}
public int getOld() {
return old;
}
}
}
代码中首先构建一个user对象,然后把user对象设置进AtomicReferenc中,最后调用compareAndSet方法进行原子更新操作,实现原理同AtomicInteger里的compareAndSet方法。
如果需原子地更新某个类里的某个字段时,就需要使用原子更新字段类,Atomic
包提供了以下3个类进行原子字段更新:
-
AtomicIntegerFieldUpdater:原子更新整型的字段的更新器。
-
AtomicLongFieldUpdater:原子更新长整型字段的更新器。
-
AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起 来,可用于原子的更新数据和数据的版本号,可以解决使用CAS进行原子更新时可能出现的
ABA
问题。
要想原子地更新字段类需要两步。
-
第一步,因为原子更新字段类都是抽象类,每次使用的时候必须使用静态方法
newUpdater()
创建一个更新器,并且需要设置想要更新的类和属性。 -
第二步,更新类的字段(属性)必须使用
public volatile
修饰符。
AstomicIntegerFieldUpdater
代码演示:
/**
-
@author xppll
-
@date 2022/1/14 17:46
*/
public class AtomicIntegerFieldUpdaterTest {
//创建原子更新器,并设置需要更新的对象类和对象的属性
private static AtomicIntegerFieldUpdater a =
AtomicIntegerFieldUpdater.newUpdater(User.class, “old”);
public static void main(String[] args) {
//开始xpp的年龄
User xpp = new User(“xpp”, 10);
//长了一岁,这里输出还是旧的年龄
System.out.println(a.getAndIncrement(xpp));//10
//输出xpp现在的年龄
System.out.println(a.get(xpp));//11
}
public static class User {
private String name;
//需要更新的字段必须使用public volatile修饰符
public volatile int old;
public User(String name, int old) {
this.name = name;
this.old = old;
}
public String getName() {
return name;
}
public int getOld() {
最后
小编利用空余时间整理了一份《MySQL性能调优手册》,初衷也很简单,就是希望能够帮助到大家,减轻大家的负担和节省时间。
关于这个,给大家看一份学习大纲(PDF)文件,每一个分支里面会有详细的介绍。
这里都是以图片形式展示介绍,如要下载原文件以及更多的性能调优笔记(MySQL+Tomcat+JVM)!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!
public int getOld() {
最后
小编利用空余时间整理了一份《MySQL性能调优手册》,初衷也很简单,就是希望能够帮助到大家,减轻大家的负担和节省时间。
关于这个,给大家看一份学习大纲(PDF)文件,每一个分支里面会有详细的介绍。
[外链图片转存中…(img-0cjhK7Ff-1714686009397)]
这里都是以图片形式展示介绍,如要下载原文件以及更多的性能调优笔记(MySQL+Tomcat+JVM)!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!