一、三大生成方式概覽
| 方式 | 核心方法 | 特點 | 適用場景 |
| 系統時間 | System.currentTimeMillis() | 極簡、無狀態、分布差、不可重現 | 非關鍵場景、簡易取模 |
| Math.random() | Math.random() → double [0,1) | 靜態便利、內部用 Random、線程安全但爭用 | 簡單單線程、教學演示 |
| Random 類 | new Random() / new Random(seed) | 專業、多型別、可設種子復現、線程不安全 | 通用開發、測試、模擬 |
二、Random 類完整 API 速查
// 構造
Random() // 種子 = System.nanoTime() + 混合
Random(long seed) // 固定種子 → 序列可復現
// 基本型別
boolean nextBoolean()
void nextBytes(byte[] buf)
double nextDouble() // [0.0, 1.0)
float nextFloat() // [0.0, 1.0)
int nextInt() // 全 int 範圍
int nextInt(int bound) // [0, bound) —— 最常用
long nextLong()
double nextGaussian() // 正態分佈 μ=0, σ=1
// 進階
void setSeed(long seed) // 重置種子(同步方法)
三、實戰代碼範例
1. 取模獲取區間整數
// 方式 1:系統時間
long l = System.currentTimeMillis();
int i1 = (int) (l % 100); // [0, 100)
// 方式 2:Math.random()
double d = Math.random();
int i2 = (int) (d * 100); // [0, 100)
// 方式 3:Random(推薦)
Random r = new Random();
int i3 = r.nextInt(100); // [0, 100) 分布均勻
2. 固定種子驗證可復現性
Random r1 = new Random(1000);
Random r2 = new Random(1000);
System.out.println(r1.nextInt(100) == r2.nextInt(100)); // true
System.out.println(r1.nextDouble() == r2.nextDouble()); // true
3. 多線程環境下的 ThreadLocalRandom(Java 7+)
// 無爭用、效能優於共享 Random
int v = ThreadLocalRandom.current().nextInt(100);
4. 安全級隨機數 SecureRandom
// 密碼學安全、種子來自 OS entropy pool、較慢
SecureRandom sr = new SecureRandom();
byte[] token = new byte[32];
sr.nextBytes(token); // 生成安全 Token、Session ID
四、常見陷阱與優化
- 種子碰撞:頻繁
new Random() 在高併發下可能產生相同種子(nanoTime 精度限制),改用 ThreadLocalRandom 或單例共享。
nextInt(bound) 偏差:JDK 內部用拒絕採樣消除模運算偏差,直接呼叫最安全。
- 效能:
ThreadLocalRandom > Random > Math.random() > SecureRandom。
- 可序列化:
Random 實現 Serializable,可持久化狀態;ThreadLocalRandom 不可。
五、總結建議
- 一般業務:
ThreadLocalRandom.current().nextInt(bound)。
- 需復現測試:
new Random(fixedSeed)。
- 安全敏感:
SecureRandom。
- 科學計算正態分佈:
Random.nextGaussian()。
- 避免在熱點路徑頻繁創建
Random 實例。