Math.random() — 輕量級靜態工具java.lang.Math.random() 為靜態方法,無需匯入即可使用(java.lang.* 自動載入)。它回傳 double 值,範圍 [0.0, 1.0)(含 0、不含 1)。
public class RandomDemo {
public static void main(String[] args) {
// 1. 直接取得 0.0~1.0 之間的 double
double d1 = Math.random();
System.out.println("0~1: " + d1);
// 2. 擴大範圍:0.0 ~ 1000.0
double d2 = Math.random() * 1000;
System.out.println("0~1000: " + d2);
// 3. 取整數:0 ~ 999
int i = (int) (Math.random() * 1000);
System.out.println("整數 0~999: " + i);
}
}
優點:語法簡潔、零設定。
缺點:僅能產生 double、難以指定種子、多執行緒下效能較差(內部同步)。
java.util.Random — 功能完整的產生器物件需 import java.util.Random;。提供多樣化的 nextXxx() 方法,支援指定種子,適合需要可重現序列或高效能場景。
| 方法 | 回傳型別 | 範圍/說明 |
|---|---|---|
nextInt() | int | 完整 int 範圍(負數包含) |
nextInt(n) | int | [0, n),常用於指定上界 |
nextLong() | long | 完整 long 範圍 |
nextFloat() | float | [0.0f, 1.0f) |
nextDouble() | double | [0.0, 1.0) |
nextBoolean() | boolean | true/false 機率各半 |
nextGaussian() | double | 高斯分佈(平均 0、標準差 1) |
import java.util.Random;
public class RandomSeedDemo {
public static void main(String[] args) {
// 固定種子 = 固定序列
Random r1 = new Random(100L);
Random r2 = new Random(100L);
System.out.println("相同種子產生的前 5 個 nextInt():");
for (int i = 0; i < 5; i++) {
System.out.printf("%d\t%d%n", r1.nextInt(), r2.nextInt());
}
// 輸出完全一致,證明序列可重現
}
}
種子來源:預設使用 System.nanoTime()(Java 8+)或 System.currentTimeMillis()。若需加密級隨機,請改用 java.security.SecureRandom。
多執行緒高併發場景下,Random 因共用種子會產生鎖競爭。改用:
import java.util.concurrent.ThreadLocalRandom;
// 直接取得當前執行緒專屬的 Random 實例
int bounded = ThreadLocalRandom.current().nextInt(1, 101); // 1~100
double d = ThreadLocalRandom.current().nextDouble(5.0, 10.0); // 5.0~10.0
無需實例化、無同步開銷、API 更豐富(支援 nextInt(origin, bound) 直接指定雙邊界)。
| 場景 | 推薦類別 | 理由 |
|---|---|---|
| 一次性、簡單腳本、單執行緒 | Math.random() | 零引用、一行搞定 |
| 需指定種子(測試、模擬重現) | Random(seed) | 序列完全可控 |
| 高併發、多執行緒 | ThreadLocalRandom | 無鎖、效能最佳 |
| 加密、安全令牌、Session ID | SecureRandom | 密碼學安全 |
掌握這兩大核心技法與進階選型,即可應對從簡單腳本到高併發系統的各類隨機需求。