1、内存的分配和释放
目录
一、介绍
二、获取类
三、功能介绍
2、park和
3、跨方法锁
4、cas
一、介绍
提供了一系列方法。具体功能有cas、内存申请与释放、park和、内存屏障、跨方法锁(jdk11不再提供该方法)。
二、获取类
我们一般有以下的几种方法去使用一个类,但是在这里我们只能使用反射来获取使用。
通过构造方法。类的构造方法被修饰,所以我们不能通过new的方式通过。通过继承。类被final修饰,所以我们也不能通过继承的方式使用他。通过暴露出来的方法。提供了静态方法(),但是get方法会对调用该方法的类加载器进行判定,我们调用该方法的类加载器是,也是不行的。通过反射。这里获取类就是通过反射实现的。
package tools.unsafe;import sun.misc.Unsafe;import java.lang.reflect.Field;/*** @Auther: duanYL* @Date: 2023/10/26/10:54* @Description:*/
public class GetUnsafe {public static void main(String[] args) {Unsafe unsafe = getUnsafeInstance();System.out.println(unsafe);}public static Unsafe getUnsafeInstance() {try {Field field = Unsafe.class.getDeclaredField("theUnsafe");field.setAccessible(true);return (Unsafe) field.get(null);} catch (Exception e) {e.printStackTrace();}return null;}
}
三、功能介绍 1、内存的分配和释放
分配的是系统内存,不被JVM管理,所以还要手动释放
package tools.unsafe;import sun.misc.Unsafe;public class AllocateMemoryAccess {public static void main(String[] args) {Unsafe unsafe = UnsafeInstance.getUnsafeInstance();long temp = 123456789L;byte size = 8;/** 调用allocateMemory分配内存*/long memoryAddress = unsafe.allocateMemory(size);System.out.println("分配的地址 :-> "+memoryAddress);/** 写入到内存中*/unsafe.putAddress(memoryAddress, temp);/** 内存中读取数据*/long readValue = unsafe.getAddress(memoryAddress);System.out.println("从指定地址取得的value : " + readValue);unsafe.freeMemory(memoryAddress);}@Overrideprotected void finalize() throws Throwable {super.finalize();}
}
2、park和
package tools.unsafe;import sun.misc.Unsafe;import java.util.concurrent.TimeUnit;/*** @Auther: duanYL* @Date: 2023/10/26/13:56* @Description:*/
public class TestParkAndUnPark {public static void main(String[] args) {Unsafe unsafe = UnsafeInstance.getUnsafeInstance();Thread thread = new Thread(() -> {//如果第一个参数为true,则会实现定时System.out.println("thread park !");unsafe.park(false,0);System.out.println("thread unpark !");});thread.start();try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("唤醒线程!!");unsafe.unpark(thread);}
}
3、跨方法锁
锁住的是一个方法的一块区域,但是提供的锁,可以在不同的方法里面加锁释放。这个方法在jdk11就不再提供了。
4、cas
(this, , old, )保证了同一时间只有一个线程能改变该值。其中是在类中,temp变量所在的内存位置。
package tools.unsafe;import sun.misc.Unsafe;/*** @Auther: duanYL* @Date: 2023/10/26/14:09* @Description:*/
public class TestCAS {static final Unsafe unsafe = UnsafeInstance.getUnsafeInstance();private volatile int temp;private static final long valueOffTemp;public TestCAS(int temp){this.temp=temp;}public int getTemp(){return this.temp;}public static void main(String[] args) throws NoSuchFieldException {TestCAS testCAS = new TestCAS(0);System.out.println("改变前的值:" + testCAS.getTemp());testCAS.compareAndSwapInt(0,1);System.out.println("改变后的值:" + testCAS.getTemp());}static {try {valueOffTemp = unsafe.objectFieldOffset(TestCAS.class.getDeclaredField("temp"));System.out.println("valueOffset:--->"+valueOffTemp);} catch (NoSuchFieldException e) {throw new RuntimeException(e);}}public boolean compareAndSwapInt(int old,int target){return unsafe.compareAndSwapInt(this, valueOffTemp, old, target);}
}
总结