隨機數是遊戲、加密、採樣、測試等場景的基礎設施。Java 提供 Math.random() 與 java.util.Random 兩種主流方式,本文對比其特性、適用場景與陷阱。
double,範圍 [0.0, 1.0)Random 實例(int)(Math.random() * n) → [0, n) 整數// 產生 0~99 隨機整數
int r = (int) (Math.random() * 100);
適用:簡單臨時需求、單線程或低併發場景。
nextInt(n) 直接產生 [0, n) 整數,n 必須為正數,否則拋 IllegalArgumentExceptionnextLong()、nextDouble()、nextBoolean()、nextGaussian() 等分布Random r1 = new Random(123L);
Random r2 = new Random(123L);
System.out.println(r1.nextInt(2000) == r2.nextInt(2000)); // true
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 一般業務邏輯、測試資料 | ThreadLocalRandom.current() (Java 7+) | 無競爭、效能優於共享 Random |
| 高併發環境 | ThreadLocalRandom 或 SplittableRandom (Java 8+) | 無鎖設計、支援分治並行 |
| 加密、安全令牌、金融級 | SecureRandom | 密碼學強度、不可預測 |
| 可複現測試、除錯 | new Random(fixedSeed) | 確定性序列 |
Random 非線程安全,多線程共享實例會導致種子爭用、效能下降nextInt(n) 參數為負數直接拋異常,務必校驗