赞
踩
本文对Java中的Unsafe类及其常见功能进行总结。
Unsafe类主要用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,其实现依赖于本地方法(Native method,用其他语言(如C/C++/汇编)编写的)
import sun.misc.Unsafe; import java.lang.reflect.Field; public class UnsafeUtils { private static final Unsafe unsafe; static { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); } catch (Exception e) { throw new RuntimeException("Unable to get Unsafe instance", e); } } public static Unsafe getUnsafe() { return unsafe; } }
1. 内存操作(分配、写入、读取)
(1)Unsafe类提供的内存操作方法
(2)示例:
import sun.misc.Unsafe; import java.lang.reflect.Field; public class UnsafeExample { private static final Unsafe unsafe; private static final long BYTE_ARRAY_BASE_OFFSET; static { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); // 获取 byte[] 数组中第一个元素的偏移量 BYTE_ARRAY_BASE_OFFSET = unsafe.arrayBaseOffset(byte[].class); } catch (Exception e) { throw new RuntimeException("Unable to get Unsafe instance", e); } } public static void main(String[] args) { // 分配 10 个字节的内存 long memoryAddress = unsafe.allocateMemory(10L); try { // 在内存中写入值 for (int i = 0; i < 10; i++) { unsafe.putByte(memoryAddress + i, (byte) (i + 1)); } // 从内存中读取值 for (int i = 0; i < 10; i++) { byte value = unsafe.getByte(memoryAddress + i); System.out.println("Value at index " + i + ": " + value); } // 使用 Unsafe 访问数组元素 byte[] byteArray = new byte[10]; for (int i = 0; i < 10; i++) { unsafe.putByte(byteArray, BYTE_ARRAY_BASE_OFFSET + i, (byte) (i + 11)); } for (int i = 0; i < 10; i++) { byte value = unsafe.getByte(byteArray, BYTE_ARRAY_BASE_OFFSET + i); System.out.println("Array value at index " + i + ": " + value); } } finally { // 释放内存 unsafe.freeMemory(memoryAddress); } } }
2. 内存屏障
(1)内存屏障(Memory Barrier)是用于防止编译器和 CPU 对指令的重新排序,以确保特定的操作顺序对所有处理器和线程都是一致的。
(2) Unsafe类提供的实现内存屏障的方法如下:
(3)示例:
public class UnsafeMemoryBarrierExample { private static final Unsafe unsafe; static { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); } catch (Exception e) { throw new RuntimeException("Unable to get Unsafe instance", e); } } private volatile int sharedVar = 0; public void storeFenceExample() { // 写操作前插入 storeFence unsafe.storeFence(); sharedVar = 42; unsafe.storeFence(); // 确保所有存储操作在此之前完成 } public void loadFenceExample() { unsafe.loadFence(); int value = sharedVar; unsafe.loadFence(); // 确保所有加载操作在此之后完成 } public void fullFenceExample() { unsafe.fullFence(); sharedVar = 42; int value = sharedVar; unsafe.fullFence(); // 确保所有存储和加载操作在此之前完成 } public static void main(String[] args) { UnsafeMemoryBarrierExample example = new UnsafeMemoryBarrierExample(); example.storeFenceExample(); example.loadFenceExample(); example.fullFenceExample(); } }
(4)Unsafe类实现内存屏障和Volatile关键字区别
特性 | Unsafe 类的内存屏障 | volatile 关键字 |
---|---|---|
用途 | 手动控制内存操作顺序 | 确保变量的可见性和有序性 |
实现复杂度 | 高,需要手动插入内存屏障 | 低,通过关键字声明 |
内存屏障类型 | storeFence() , loadFence() , fullFence() | 内置,隐式插入 |
代码可读性 | 低,可读性差,难以维护 | 高,简洁明了 |
编译器重排序防护 | 是,通过显式屏障 | 是,通过内置机制 |
CPU重排序防护 | 是,通过显式屏障 | 是,通过内置机制 |
使用场景 | 高性能、低延迟需求,需精准控制的场合 | 一般并发编程,需确保变量可见性的场合 |
跨平台兼容性 | 低,依赖具体 JVM 实现,不保证一致性 | 高,由 JVM 提供保障 |
线程安全 | 是,但需手动确保正确性 | 是,由关键字保证 |
内存开销 | 较低,只影响屏障附近代码 | 较高,影响整个变量的读写 |
典型用法 | 高性能并发库,如 java.util.concurrent | 通用多线程应用 |
故障风险 | 高,不正确使用可能导致崩溃或数据损坏 | 低,由 JVM 保证 |
(3)CAS 操作
(1) CAS(Compare-And-Swap)操作是一种原子操作,用于实现无锁并发编程,是一种乐观锁的形式。
(2) Unsafe 类提供了多种 CAS 方法,包括compareAndSwapInt、compareAndSwapLong 和 compareAndSwapObject。
(3)Java中的synchronized关键字和抽象队列同步器的底层实现都使用到了CAS操作。
(4)示例:
public class UnsafeCASExample { private static final Unsafe unsafe; private static final long valueOffset; static { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); // 获取 value 字段的偏移量 valueOffset = unsafe.objectFieldOffset(UnsafeCASExample.class.getDeclaredField("value")); } catch (Exception e) { throw new RuntimeException("Unable to get Unsafe instance", e); } } private volatile int value; public UnsafeCASExample(int initialValue) { this.value = initialValue; } public int getValue() { return value; } public boolean compareAndSwapValue(int expectedValue, int newValue) { return unsafe.compareAndSwapInt(this, valueOffset, expectedValue, newValue); } public static void main(String[] args) { UnsafeCASExample example = new UnsafeCASExample(0); // 多线程更新 value Runnable task = () -> { for (int i = 0; i < 1000; i++) { int oldValue; int newValue; do { oldValue = example.getValue(); newValue = oldValue + 1; } while (!example.compareAndSwapValue(oldValue, newValue)); } }; Thread thread1 = new Thread(task); Thread thread2 = new Thread(task); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("Final value: " + example.getValue()); } }
4. 线程调度
(1) Unsafe 类不仅提供了底层的内存操作,还提供了一些与线程操作相关的方法,包括暂停、恢复和阻塞线程等。
public class UnsafeThreadExample { private static final Unsafe unsafe; static { try { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); unsafe = (Unsafe) field.get(null); } catch (Exception e) { throw new RuntimeException("Unable to get Unsafe instance", e); } } public static void main(String[] args) { Thread parker = new Thread(() -> { System.out.println("Thread is going to park"); unsafe.park(false, 0); System.out.println("Thread is unparked"); }); Thread unparker = new Thread(() -> { try { Thread.sleep(1000); // Sleep for a while before unparking } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("Thread will unpark the parked thread"); unsafe.unpark(parker); }); parker.start(); unparker.start(); try { parker.join(); unparker.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
5. 其他功能
Unsafe还提供一些其他的功能,包括:对象操作、数据操作、Class 操作、系统信息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。