Java如何使用Unsafe类
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章将为大家详细讲解有关Java如何使用Unsafe类,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Unsafe 对象提供了非常底层的,操作内存、线程的方法,相
千家信息网最后更新 2026年11月02日Java如何使用Unsafe类
这篇文章将为大家详细讲解有关Java如何使用Unsafe类,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
Unsafe 对象提供了非常底层的,操作内存、线程的方法,相当于开了后门。
在atomic类中CAS实现、LockSupport中park unpark的底层都调用了UnSafe中的方法。
UnSafe并不是说线程不安全,而是说操作内存有可能会造成不安全问题。
当然对于开发人员来说
Unsafe 对象不能直接调用,只能通过反射获得
通过反射获得Unsafe对象
package com.dongguo.unsafe;import sun.misc.Unsafe;import java.lang.reflect.Field;/** * @author Dongguo * @date 2021/9/12 0012-21:32 * @description: */public class UnsafeAccessor { static Unsafe unsafe; static { try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); unsafe = (Unsafe) theUnsafe.get(null); } catch (NoSuchFieldException | IllegalAccessException e) { throw new Error(e); } } static Unsafe getUnsafe() { return unsafe; } public static void main(String[] args) { Unsafe unsafe = getUnsafe(); System.out.println(unsafe); }}运行结果
sun.misc.Unsafe@7ea987ac
使用Unsafe实现 CAS 操作
package com.dongguo.unsafe;import lombok.Data;import sun.misc.Unsafe;import java.lang.reflect.Field;/** * @author Dongguo * @date 2021/9/12 0012-21:32 * @description: */public class UnsafeAccessor { static Unsafe unsafe; static { try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); unsafe = (Unsafe) theUnsafe.get(null); } catch (NoSuchFieldException | IllegalAccessException e) { throw new Error(e); } } static Unsafe getUnsafe() { return unsafe; } public static void main(String[] args) throws NoSuchFieldException { Unsafe unsafe = getUnsafe(); System.out.println(unsafe); Field id = Student.class.getDeclaredField("id"); Field name = Student.class.getDeclaredField("name"); // 获得成员变量的偏移量 long idOffset = unsafe.objectFieldOffset(id); long nameOffset = unsafe.objectFieldOffset(name); Student student = new Student(); // 使用 cas 方法替换成员变量的值 unsafe.compareAndSwapInt(student, idOffset, 0, 20); // 返回 true 0为旧值 20为新值 unsafe.compareAndSwapObject(student, nameOffset, null, "张三"); // 返回 true 旧值为null,新值为张三 System.out.println(student); }}@Dataclass Student { volatile int id; volatile String name;}运行结果
sun.misc.Unsafe@7ea987ac
Student(id=20, name=张三)
直接使用Unsafe类实现之前AtomicIntegerFieldUpdater中线程安全的原子整数 BankAccount
在atomic中使用AtomicIntegerFieldUpdater实现money线程安全的原子整数
package com.dongguo.unsafe;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;/** * @author Dongguo * @date 2021/9/7 0007-14:41 * 以一种线程安全的方式操作非线程安全对象的某些字段。 * 需求: * 1000个人同时向一个账号转账一元钱,那么累计应该增加1000元, * 除了synchronized和CAS,还可以使用AtomicIntegerFieldUpdater来实现。 */class BankAccount { private String bankName = "ACBC"; public volatile int money = 0; AtomicIntegerFieldUpdater fieldUpdater = AtomicIntegerFieldUpdater.newUpdater(BankAccount.class, "money"); public void transferMoney(BankAccount bankAccount) { fieldUpdater.incrementAndGet(bankAccount); }}public class AtomicIntegerFieldUpdaterDemo { public static void main(String[] args) { BankAccount bankAccount = new BankAccount(); for (int i = 1; i <= 1000; i++) { new Thread(() -> { bankAccount.transferMoney(bankAccount); }, String.valueOf(i)).start(); } //暂停毫秒 try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(bankAccount.money); }} 改为使用UnSafe实现money线程安全的原子整数
package com.dongguo.unsafe;import sun.misc.Unsafe;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;/** * @author Dongguo * @date 2021/9/7 0007-14:41 */class BankAccount { private String bankName = "ACBC"; public volatile int money; static final Unsafe unsafe; static final long DATA_OFFSET; static { unsafe = UnsafeAccessor.getUnsafe(); try { // money 属性在 BankAccount 对象中的偏移量,用于 Unsafe 直接访问该属性 DATA_OFFSET = unsafe.objectFieldOffset(BankAccount.class.getDeclaredField("money")); } catch (NoSuchFieldException e) { throw new Error(e); } } public BankAccount(int money) { this.money = money; } public void transferMoney(int amount) { int oldValue; while (true) { // 获取共享变量旧值,可以在这一行加入断点,修改 data 调试来加深理解 oldValue = money; // cas 尝试修改 data 为 旧值 + amount,如果期间旧值被别的线程改了,返回 false if (unsafe.compareAndSwapInt(this, DATA_OFFSET, oldValue, oldValue + amount)) { return; } } }}public class AtomicIntegerFieldUpdaterDemo { public static void main(String[] args) { BankAccount bankAccount = new BankAccount(0); for (int i = 1; i <= 1000; i++) { new Thread(() -> { bankAccount.transferMoney(1); }, String.valueOf(i)).start(); } //暂停毫秒 try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(bankAccount.money); }}运行结果1000/暂停毫秒 try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(bankAccount.money); }}运行结果
1000
关于"Java如何使用Unsafe类"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
线程
安全
对象
结果
运行
原子
变量
整数
方法
篇文章
张三
内存
属性
底层
成员
更多
偏移
反射
不错
实用
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
瑰夏咖啡
南京欣网互联网络科技
互联网科技工作委员会主任
港股互联网科技股
互联网科技小贷
电子科技大学互联网
佩信高科技互联网
中国最先进互联网科技公司
互联网经济与金融科技
厦门千工互联网科技有限公司
互联网与医疗科技
广西互联网科技孵化中心
本届互联网博览会上的黑科技
朱啸虎曾投资哪些互联网科技企业
南通创西澳互联网科技有限公司
半导体是互联网高科技吗
半导体行业属于互联网高科技类吗
第三届互联网大会安防黑科技
互联网科技品牌
黑龙江互联网科技公司
互联网新科技
互联网科技网
互联网科技公司华为
互联网电商科技
美国互联网科技巨头监管
互联网还是高科技吗
互联网科技实习生岗位
产业互联网科技服务公司
互联网风格科技公司名称
网互联网络科技