353 int r; 354 Thread t = Thread.currentThread(); 355 if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) { 356 r ^= r << 13; // xorshift 357 r ^= r >>> 17; 358 r ^= r << 5; 359 } 360 else if ((r = (int)UNSAFE.getLong(t, SEED)) == 0) 361 r = 1; // avoid zero 362 UNSAFE.putInt(t, SECONDARY, r); 363 return r; 364 } 365 366 // Serialization support, maintains original persistent form. 367 368 private static final long serialVersionUID = -5851777807851030925L; 369 370 /** 371 * @serialField rnd long 372 * @serialField initialized boolean 373 * @serialField pad0 long 374 * @serialField pad1 long 375 * @serialField pad2 long 376 * @serialField pad3 long 377 * @serialField pad4 long 378 * @serialField pad5 long 379 * @serialField pad6 long 380 * @serialField pad7 long 381 */ 382 private static final ObjectStreamField[] serialPersistentFields = { 383 new ObjectStreamField("rnd", long.class), 384 new ObjectStreamField("initialized", boolean.class), 385 new ObjectStreamField("pad0", long.class), 386 new ObjectStreamField("pad1", long.class), 387 new ObjectStreamField("pad2", long.class), 388 new ObjectStreamField("pad3", long.class), 389 new ObjectStreamField("pad4", long.class), 390 new ObjectStreamField("pad5", long.class), 391 new ObjectStreamField("pad6", long.class), 392 new ObjectStreamField("pad7", long.class) }; 393 394 /** 395 * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it). 396 */ 397 private void writeObject(java.io.ObjectOutputStream out) 398 throws java.io.IOException { 399 400 java.io.ObjectOutputStream.PutField fields = out.putFields(); 401 fields.put("rnd", 0L); 402 fields.put("initialized", true); 403 fields.put("pad0", 0L); 404 fields.put("pad1", 0L); 405 fields.put("pad2", 0L); 406 fields.put("pad3", 0L); 407 fields.put("pad4", 0L); 408 fields.put("pad5", 0L); 409 fields.put("pad6", 0L); 410 fields.put("pad7", 0L); 411 out.writeFields(); 412 } 413 414 /** 415 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}. 416 */ 417 private Object readResolve() { 418 return current(); 419 } 420 421 // Unsafe mechanics 422 private static final sun.misc.Unsafe UNSAFE; 423 private static final long SEED; 424 private static final long PROBE; 425 private static final long SECONDARY; 426 static { 427 try { 428 UNSAFE = sun.misc.Unsafe.getUnsafe(); 429 Class<?> tk = Thread.class; 430 SEED = UNSAFE.objectFieldOffset | 353 int r; 354 Thread t = Thread.currentThread(); 355 if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) { 356 r ^= r << 13; // xorshift 357 r ^= r >>> 17; 358 r ^= r << 5; 359 } 360 else if ((r = (int)UNSAFE.getLong(t, SEED)) == 0) 361 r = 1; // avoid zero 362 UNSAFE.putInt(t, SECONDARY, r); 363 return r; 364 } 365 366 // Serialization support, maintains original persistent form. 367 368 private static final long serialVersionUID = -5851777807851030925L; 369 370 /** 371 * @serialField rnd long 372 * @serialField initialized boolean 373 */ 374 private static final ObjectStreamField[] serialPersistentFields = { 375 new ObjectStreamField("rnd", long.class), 376 new ObjectStreamField("initialized", boolean.class) }; 377 378 /** 379 * Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it). 380 */ 381 private void writeObject(java.io.ObjectOutputStream out) 382 throws java.io.IOException { 383 384 java.io.ObjectOutputStream.PutField fields = out.putFields(); 385 fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED)); 386 fields.put("initialized", true); 387 out.writeFields(); 388 } 389 390 /** 391 * Returns the {@link #current() current} thread's {@code ThreadLocalRandom}. 392 */ 393 private Object readResolve() { 394 return current(); 395 } 396 397 // Unsafe mechanics 398 private static final sun.misc.Unsafe UNSAFE; 399 private static final long SEED; 400 private static final long PROBE; 401 private static final long SECONDARY; 402 static { 403 try { 404 UNSAFE = sun.misc.Unsafe.getUnsafe(); 405 Class<?> tk = Thread.class; 406 SEED = UNSAFE.objectFieldOffset |