Unsafe类
目录一、概述二、内存操作1.DirectByteBuffer类三、内存屏障四、CAS操作五、数组操作1.AtomicIntegerArray类六、线程调度1.AbstractQueuedSynchronizer类AQS一、概述Unsafe类可以直接访问系统内存资源、自主管理内存资源由于过于底层不建议自己调用Unsafe类自主分配的内存资源可能与JVM冲突容易造成JVM异常但是JUC又经常使用这个类所以有必要了解其原理。Unsafe对象是单例的publicfinalclassUnsafe{// 单例对象privatestaticfinalUnsafetheUnsafe;......privateUnsafe(){}CallerSensitivepublicstaticUnsafegetUnsafe(){Classvar0Reflection.getCallerClass();// 仅在引导类加载器BootstrapClassLoader加载时才合法if(!VM.isSystemDomainLoader(var0.getClassLoader())){thrownewSecurityException(Unsafe);}else{returntheUnsafe;}}}只能基于反射获取Unsafe对象通过getUnsafe()方法获取会抛异常privatestaticUnsafereflectGetUnsafe(){try{FieldfieldUnsafe.class.getDeclaredField(theUnsafe);field.setAccessible(true);return(Unsafe)field.get(null);}catch(Exceptione){log.error(e.getMessage(),e);returnnull;}}二、内存操作Unsafe类提供了如下接口操作内存不仅可以操作JVM堆内存还能操作JVM外的内存。//获取内存空间返回内存空间地址publicnativelongallocateMemory(longbytes);//重新调整内存空间的大小当address后的空间足够扩容则会原地扩容否则拷贝数据到新的内存空间并返回地址publicnativelongreallocateMemory(longaddress,longbytes);//将内存设置为指定值publicnativevoidsetMemory(Objecto,longoffset,longbytes,bytevalue);//内存拷贝publicnativevoidcopyMemory(ObjectsrcBase,longsrcOffset,ObjectdestBase,longdestOffset,longbytes);//释放内存publicnativevoidfreeMemory(longaddress);1.DirectByteBuffer类DirectByteBuffer类用于申请堆外内存底层就是调用Unsafe类的API。I/O过程中会将数据从JVM堆内存拷贝到堆外内存有一定耗时所以将频繁I/O的数据直接存储到堆外内存能够提升性能。DirectByteBuffer(intcap){super(-1,0,cap,cap);booleanpaVM.isDirectMemoryPageAligned();intpsBits.pageSize();longsizeMath.max(1L,(long)cap(pa?ps:0));Bits.reserveMemory(size,cap);longbase0;try{// 分配内存并返回基地址baseunsafe.allocateMemory(size);}catch(OutOfMemoryErrorx){Bits.unreserveMemory(size,cap);throwx;}// 内存初始化unsafe.setMemory(base,size,(byte)0);if(pa(base%ps!0)){// Round up to page boundaryaddressbaseps-(base(ps-1));}else{addressbase;}// 构建Cleaner对象用于跟踪DirectByteBuffer对象的垃圾回收以实现当DirectByteBuffer被垃圾回收时分配的堆外内存一起被释放cleanerCleaner.create(this,newDeallocator(base,size,cap));attnull;}三、内存屏障内存屏障用于确保主内存和多线程工作内存中数据的同步保证数据可见性。Java线程volatile关键字解决可见性//内存屏障禁止读操作重排序。publicnativevoidloadFence();//内存屏障禁止store操作重排序。publicnativevoidstoreFence();//内存屏障禁止读写操作重排序publicnativevoidfullFence();写内存屏障对于写操作首先会修改当前线程工作内存的数据然后将其写回主内存但这是两步操作期间其他线程仍然能够读到主内存的旧数据。写内存屏障就是为了立即将屏障之前的写操作结果刷新到主内存确保两步操作期间其他线程必须等待。并结合缓存一致性协议将其他处理器线程工作内存的缓存行设置为无效但是缓存一致性协议是异步的期间其他线程仍然能操作其工作内存中的旧数据所以应该结合读内存屏障使用。读内存屏障对于读操作首先会从主内存读数据到工作内存然后操作工作内存的数据但是操作数据期间主内存的数据可能已经被修改了此时工作内存中的数据是脏数据。读内存屏障就是确保在屏障之后的读操作都能看到最新的数据。在多处理器系统中由于缓存一致性协议不是瞬时的一个处理器对共享数据的修改可能不会立即被其他处理器看到。其他处理器的缓存中可能还存有旧的数据而读屏障可以强制该处理器线程等待缓存一致性协议将已修改的缓存失效后等待失效队列中的一致性协议都执行完毕才执行读屏障后的读操作从主内存重新加载数据从而确保读取到最新的值。全内存屏障读屏障写屏障保证屏障之前的写操作对屏障之后的读操作立即可见。CAS保证读主内存到工作内存-修改工作内存-写回主内存整体作为一个原子操作但不保证其他工作空间中的数据失效。写内存屏障保证修改工作内存-写回主内存整体作为一个原子操作但不保证其他工作空间中的数据失效。读内存屏障保证工作内存中的数据立即失效即绕过工作内存直接读主内存。publicclassMyThreadextendsThread{booleanflagfalse;Overridepublicvoidrun(){System.out.println(thread线程执行,flagflag);flagtrue;reflectGetUnsafe().storeFence();System.out.println(thread线程执行,flagflag);}publicstaticvoidmain(String[]args)throwsInterruptedException{MyThreadthreadnewMyThread();thread.start();System.out.println(main线程执行,flagthread.flag);reflectGetUnsafe().loadFence();System.out.println(main线程执行,flagthread.flag);}}四、CAS操作CAS是一条CPU原子指令cmpxchg指令Unsafe提供的CAS方法底层实现即为cmpxchg用于实现乐观锁。 Java线程 CAS乐观锁、AtomicInteger类源码五、数组操作//返回数组中第一个元素的地址publicnativeintarrayBaseOffset(Class?arrayClass);//返回数组中一个元素占用的大小publicnativeintarrayIndexScale(Class?arrayClass);1.AtomicIntegerArray类AtomicIntegerArray可以实现对Integer数组中每个元素的原子性操作就是通过Unsafe类的arrayBaseOffset、arrayIndexScale进行数组中元素的定位然后通过CAS实现原子性操作。六、线程调度//取消阻塞线程publicnativevoidunpark(Objectthread);//阻塞线程publicnativevoidpark(booleanisAbsolute,longtime);//获得对象锁可重入锁DeprecatedpublicnativevoidmonitorEnter(Objecto);//释放对象锁DeprecatedpublicnativevoidmonitorExit(Objecto);//尝试获取对象锁DeprecatedpublicnativebooleantryMonitorEnter(Objecto);1.AbstractQueuedSynchronizer类AQSAQS详解publicstaticvoidpark(Objectblocker){ThreadtThread.currentThread();setBlocker(t,blocker);UNSAFE.park(false,0L);setBlocker(t,null);}publicstaticvoidunpark(Threadthread){if(thread!null)UNSAFE.unpark(thread);}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2419642.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!