Java Unsafe 测试代码
Java Unsafe 测试代码
import com.User;
import org.junit.Before;
import org.junit.Test;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
class User {
public static String USER_CLASS_NAME = "User.class";
private int age;
private String name;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public User(int age, String name) {
this.age = age;
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
public class LockTests {
Unsafe unSafe;
User u = new User(17, "zhangsan");
@Before
public void before() throws Exception {
Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeField.setAccessible(true);
unSafe = (Unsafe) theUnsafeField.get(Unsafe.class);
}
@Test
public void objectFieldOffset() throws Exception {
// unSafe偏底层的一个Java工具类
java.util.List users = new ArrayList();
for (int i = 0; i < 10; i++) {
Field ageField = User.class.getDeclaredField("age");
User u = new User(18, "daxin");
users.add(u);
//使用内存获取User age字段在内存中的 offset
// 是相对地址,不是一个绝对地址
long ageOffset = unSafe.objectFieldOffset(ageField);
// 每次都相同
System.out.println("ageOffset = " + ageOffset);
}
}
@Test
public void compareAndSwapInt() throws Exception {
// unSafe偏底层的一个Java工具类
Field ageField = User.class.getDeclaredField("age");
User u = new User(18, "daxin");
//使用内存获取User age字段在内存中的 offset
long ageOffset = unSafe.objectFieldOffset(ageField);
// 修改之前的值
System.out.println(u.getAge());
// 进行CAS更新, 由于设置18 因此CAS 会成功
unSafe.compareAndSwapInt(u, ageOffset, 18, 20);
System.out.println(u.getAge());
// 由于age设置20 进行CAS失败
unSafe.compareAndSwapInt(u, ageOffset, 18, 22);
System.out.println(u.getAge());
}
@Test
public void ensureClassInitialized() {
System.out.println("==== start ====");
unSafe.ensureClassInitialized(ClassIsLoad.class);
// 再次 确认不会报错
unSafe.ensureClassInitialized(ClassIsLoad.class);
}
/**
* AQS 底层的Node链表就是基于这个工具实现的 。
*
* @throws Exception
*/
@Test
public void getValueByFieldOffset() throws Exception {
for (int i = 0; i < 10; i++) {
User u = new User(18, UUID.randomUUID().toString().substring(i, 20));
int age = unSafe.getInt(u, 12L);
System.out.println("age = " + age);
// 获取名字 field offset
Field nameField = User.class.getDeclaredField("name");
long nameOffset = unSafe.objectFieldOffset(nameField);
System.out.println("nameOffset = " + nameOffset);
String name = unSafe.getObject(u, nameOffset) + "";
System.out.println("name = " + name);
}
}
@Test
public void pageSize() {
System.out.println("unSafe.pageSize() = " + unSafe.pageSize());
}
/**
* AtomicInteger 底层是基于getAndAddInt实现
*/
@Test
public void getAndAddInt() throws InterruptedException {
User u = new User(17, "zhangsan");
CountDownLatch downLatch = new CountDownLatch(10);
System.out.println("u.getAge() = " + u.getAge());
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
downLatch.countDown();
int val = unSafe.getAndAddInt(u, 12L, 1);
System.out.println(Thread.currentThread().getName() + " val = " + val);
}
}).start();
}
Thread.sleep(5000);
System.out.println("u.getAge() = " + u.getAge());
}
@Test
public void getAndSetInt() throws InterruptedException {
User u = new User(17, "zhangsan");
CountDownLatch downLatch = new CountDownLatch(10);
System.out.println("u.getAge() = " + u.getAge());
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
downLatch.countDown();
int val = unSafe.getAndSetInt(u, 12L, 10);
System.out.println(Thread.currentThread().getName() + " val = " + val);
}
}).start();
}
Thread.sleep(5000);
System.out.println("u.getAge() = " + u.getAge());
}
@Test
public void getIntVolatile() {
for (int i = 0; i < 10; i++) {
u.setAge(i);
/**
* @param obj the object containing the field to modify.
* @param offset the offset of the integer field within <code>obj</code>.
* @return
*/
int age = unSafe.getIntVolatile(u, 12L);
System.out.println("age = " + age);
}
}
// 系统负载采样的接口
@Test
public void getLoadAverage() {
double[] nums = new double[8];
int val = unSafe.getLoadAverage(nums, 8);
System.out.println(val);
}
/**
* //内存屏障,禁止load操作重排序。屏障前的load操作不能被重排序到屏障后,屏障后的load操作不能被重排序到屏障前
* public native void loadFence();
* <p>
* <p>
* 参见:https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html
*/
@Test
public void loadFence() {
//java.util.concurrent.locks.StampedLock.validate
unSafe.loadFence();
}
/**
* //内存屏障,禁止store操作重排序。屏障前的store操作不能被重排序到屏障后,屏障后的store操作不能被重排序到屏障前
* public native void storeFence();
* 参见:https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html
*/
@Test
public void storeFence() {
}
/**
* //内存屏障,禁止load、store操作重排序
* public native void fullFence();
* 参见:https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html
*/
@Test
public void fullFence() {
}
@Test
public void shouldBeInitialized() {
boolean shouldBeInitialized = unSafe.shouldBeInitialized(String.class);
System.out.println(shouldBeInitialized);
shouldBeInitialized = unSafe.shouldBeInitialized(User.class);
System.out.println(shouldBeInitialized);
}
/**
* synchronized 的一种实现获取锁
*
* @throws InterruptedException
*/
@Test
public void monitorEnter() throws InterruptedException {
unSafe.monitorEnter(u);
new Thread(new Runnable() {
@Override
public void run() {
synchronized (u) {
System.out.println("==u lock got ==");
}
}
}).start();
Thread.sleep(2000);
unSafe.monitorExit(u);
}
@Test
public void compareAndSwap() {
// unSafe.compareAndSwapInt(对象, 对象中的字段偏移, 期望值, 设置值)
// unSafe.compareAndSwapLong(对象, 对象中的字段偏移, 期望值, 设置值)
// unSafe.compareAndSwapObject(对象, 对象中的字段偏移, 期望值, 设置值)
}
@Test
public void t() {
// 方法签名
// public void copyMemory(Object srcBase, long srcOffset,Object destBase, long destOffset, long bytes)
// unSafe.copyMemory();
}
}
class ClassIsLoad {
static {
System.out.println("ClassIsLoad class Is Load !");
}
}

![Java Unsafe 测试代码
[编程语言教程]](https://www.zixueka.com/wp-content/uploads/2024/01/1706712396-85b6f9327cd6ae4.jpg)
