1、实例化sun.misc.Unsafe
Unsafe 有一public 方法:getUnsafe() , 返回值是Unsafe的实例。如果直接调用会抛: Exception in thread "main" java.lang.SecurityException: Unsafe。
有这样一段说明: Although the class and all methods are public, use of this class is limited because only trusted code can obtain instances of it. 所以只有java认为是安全的代码才可以获取Unsafe实例。
如果你尝试创建Unsafe类的实例,基于以下两种原因是不被允许的。
- 1)、Unsafe类的构造函数是私有的;
- 2)、虽然它有静态的getUnsafe()方法,但是如果你尝试调用Unsafe.getUnsafe(),会得到一个SecutiryException。这个类只有被JDK信任的类实例化。
但是这总会是有变通的解决办法的,一个简单的方式就是使用反射进行实例化
2、测试代码:
private static Field fthreadLocalRandomSeed; private static final sun.misc.Unsafe UNSAFE; private static final long SEED; static { try { // 反射 获取threadLocalRandomSeed fthreadLocalRandomSeed = Thread.class.getDeclaredField("threadLocalRandomSeed"); fthreadLocalRandomSeed.setAccessible(true); //获取unsafe对象 Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); UNSAFE = (Unsafe) f.get(0); //虽然它有静态的getUnsafe()方法,但是如果你尝试调用Unsafe.getUnsafe(),会得到一个SecutiryException。这个类只有被JDK信任的类实例化。// UNSAFE = sun.misc.Unsafe.getUnsafe(); Class<?> tk = Thread.class; //获取threadLocalRandomSeed在thread中的偏移量 SEED = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSeed")); } catch (Exception e) { throw new Error(e); } } /** * 使用反射 读写threadLocalRandomSeed成员 */ public static void byReflection() { try { long b = System.currentTimeMillis(); Thread t = Thread.currentThread(); fthreadLocalRandomSeed.set(t,0); for (long i=0;i < 100000000;i++ ) { fthreadLocalRandomSeed.set(t,(Long)fthreadLocalRandomSeed.get(t)+1); } long e = System.currentTimeMillis(); System.out.println("byReflection spend:" + (e-b) + "ms"); } catch (Exception e) { } } /** * 使用unsafe 读写threadLocalRandomSeed成员 */ public static void byUnsafe() { UNSAFE.putLong(Thread.currentThread(),SEED,0); long b = System.currentTimeMillis(); Thread t = Thread.currentThread(); for (long i = 0;i < 100000000; i++) { UNSAFE.putLong(t,SEED,UNSAFE.getLong(t,SEED)+1); } long e = System.currentTimeMillis(); System.out.println("byUnsafe spend:" + (e-b) + "ms"); } public static void main(String[] args) { try { byUnsafe(); byReflection(); System.out.println("==============="); } catch (Exception e) { e.printStackTrace(); } }