Closed Alice52 closed 3 years ago
UNSAFE 未经保护地改变内存,会引起别的方法在使用这一段内存时报错
// 使用 unsafe 将 Test 类 value 属性的位置设置成了 long 型值 2333, // 而当使用 value 属性时,虚拟机会将这一块内存解析为 String 对象, // 原 String 对象对象头的结构被打乱了,解析对象失败抛出了错误, // 更严重的问题是报错信息中没有类名行号等信息,在复杂项目中排查这种问题真如同大海捞针 public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); Unsafe unsafe = (Unsafe) field.get(null); // Test 类是一个随手写的测试类,只有一个 String 类型的测试类 Test test = new Test(); test.ttt = "12345"; unsafe.putLong(test, 12L, 2333L); System.out.println(test.value); }
一般都是全局使用某一个 Random 实例, 在高并发下可能会导致线程阻塞
随机原理
随机的种子
core code
protected int next(int bits) { long oldseed, nextseed; AtomicLong seed = this.seed; do { oldseed = seed.get(); nextseed = (oldseed * multiplier + addend) & mask; // CAS 更新下一次随机的种子 } while (!seed.compareAndSet(oldseed, nextseed)); return (int)(nextseed >>> (48 - bits)); }
线程安全
此线程专属的随机种子
UNSAFE实现, 不是使用get/set修改是会导致违反类的封闭性原则
过程
public long nextLong() { return mix64(nextSeed()); } final long nextSeed() { Thread t = Thread.currentThread(); long r = UNSAFE.getLong(t, SEED) + GAMMA; UNSAFE.putLong(t, SEED, r); }
unsafe 12L
Object o = new Object(): 8/4 + 8 + 8/4 + 0 = 8/4 + 16
对象的内存布局
数组对象
4 字节且与压缩无关
UNSAFE 未经保护地改变内存,会引起别的方法在使用这一段内存时报错
: 里面的方法都是线程安全的Random: 线程安全 CAS
一般都是全局使用某一个 Random 实例, 在高并发下可能会导致线程阻塞
随机原理
随机的种子
core code
ThreadLocalRandom
线程安全
此线程专属的随机种子
UNSAFE实现, 不是使用get/set修改是会导致违反类的封闭性原则
过程
core code
reference