Unsafe的用法
程序员文章站
2023-12-28 18:01:34
...
我们写程序,一般不直接使用Unsafe类。 JDK的类特别是并发框架中大量使用到Unsafe的功能,比如:AtomicInteger, LockSupport.所以,了解Unsafe提供的功能与机制是非常必要的。
如何获取Unsafe对象?
功能1:操作对象的属性, 可以绕过private关键字。
功能2:直接操作DirectBuffer,高效。
功能3:线程的阻塞与唤醒:
功能4:CAS操作:
如何获取Unsafe对象?
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeInstance.setAccessible(true); return (Unsafe) theUnsafeInstance.get(Unsafe.class);
功能1:操作对象的属性, 可以绕过private关键字。
TestUnsafe a = (TestUnsafe) unsafe.allocateInstance(aClass); Field f = TestUnsafe.class.getDeclaredField("num"); long offset = unsafe.objectFieldOffset(f); unsafe.compareAndSwapInt(a, offset, 0, 2); System.out.println(a);
功能2:直接操作DirectBuffer,高效。
File counters = new File(System.getProperty("java.io.tmpdir"), "counters.deleteme"); System.out.println(counters.getAbsolutePath()); counters.deleteOnExit(); FileChannel fc = new RandomAccessFile(counters, "rw").getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024); long address = ((DirectBuffer) mbb).address(); int value = unsafe.getIntVolatile(null, address); System.out.println("---" + value); System.out.println(unsafe.compareAndSwapInt(null, address, value, 2));
功能3:线程的阻塞与唤醒:
Thread t = new Thread(new Runnable() { @Override public void run() { System.out.println("线程t阻塞"); unsafe.park(false, 0l); System.out.println("线程t唤醒"); } }); t.start(); Thread.sleep(10000); //线程挂起和恢复 // unsafe.park(false,1000*1000*1000*100); //nanosecond System.out.println("唤醒t!"); unsafe.unpark(t);
功能4:CAS操作:
TestUnsafe a = (TestUnsafe) unsafe.allocateInstance(aClass); Field f = TestUnsafe.class.getDeclaredField("num"); long offset = unsafe.objectFieldOffset(f); unsafe.compareAndSwapInt(a, offset, 0, 2); System.out.println(a);