import java.util.Random; import java.util.TreeMap; public class TestDubboRandomLoadBalance { static int turn_max = 1000; static int loop_max = 100; static double[] weight = new double[] { 0.06, 2.94, 97 }; static int[] weightArray = new int[] { 1, 1, 3 }; public static void main(String[] args) { sortTree(); sortInt(); } /** TreeMap 的 ceilingKey 原理: key值爲每一個權重值的落點範圍**/ private static void sortTree() { for (int loop = 0; loop < loop_max; loop++) { int count1 = 0, count2 = 0, count3 = 0; TreeMap<Double, Integer> map = new TreeMap<Double, Integer>(); double weightTotal = 0; for (int index = 0; index < weight.length; index++) { weightTotal += weight[index]; map.put(weightTotal, index + 1); } int turn = turn_max; while (turn > 0) { double random = (Math.random() * weightTotal); Integer index = map.get(map.ceilingKey(random)); //returns the entry for the least key greater than the specified key if (1 == index) { count1++; } else if (2 == index) { count2++; } else if (3 == index) { count3++; } --turn; } System.out.println("1-" + count1 + ";2-" + count2 + ";3-" + count3); } } /** * 1)假設有四個集羣節點A,B,C,D,對應的權重分別是1,2,3,4,那麼請求到A節點的機率就爲1/(1+2+3+4) = 10%. B,C,D節點依次類推爲20%,30%,40%. * 2)總權重爲10(1+2+3+4), 根據10隨機出一個整數,假如爲隨機出來的是2.而後依次和權重相減,好比2(隨機數)-1(A的權重) = 1, * 而後1(上一步計算的結果)-2(B的權重) = -1,此時-1 < 0,那麼則調用B,其餘的以此類推 * */ private static void sortInt() { for (int loop = 0; loop < loop_max; loop++) { int totalWeight = 0; boolean sameWeight = true; int length = weightArray.length; for (int i = 0; i < length; i++) { int weight = weightArray[i]; totalWeight += weight; if (sameWeight && i > 0 && weight != weightArray[i - 1]) { sameWeight = false; } } Random random = new Random(); int count1 = 0, count2 = 0, count3 = 0; int turn = turn_max; while (turn > 0) { int index = -1; if (totalWeight > 0 && !sameWeight) { int offset = random.nextInt(totalWeight); for (int i = 0; i < length; i++) { offset -= weightArray[i]; if (offset < 0) { index = i; break; } } } if (index == -1) { index = random.nextInt(length); } if (0 == index) { count1++; } else if (1 == index) { count2++; } else if (2 == index) { count3++; } --turn; } System.out.println("1-" + count1 + ";2-" + count2 + ";3-" + count3); } } }
tip:java
Math.class private static final class RandomNumberGeneratorHolder { static final Random randomNumberGenerator = new Random(); } public static double random() { return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble(); }
import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.stream.Collectors; public class Test { public static void main(String[] args) { Random r1 = new Random(100); Random r2 = new Random(100); List<String> l1 = new ArrayList<>(); List<String> l2 = new ArrayList<>(); for (int i = 0; i < 100; i++) { l1.add(String.valueOf(r1.nextInt(10))); l2.add(String.valueOf(r2.nextInt(10))); } System.out.println(l1.stream().collect(Collectors.joining(","))); System.out.println(String.join(",", l2)); } } 5,0,4,8,1,6,6,8,3,3,2,7,6,7,2,9,0,8,3,9,3,8,5,2,7,1,8... 5,0,4,8,1,6,6,8,3,3,2,7,6,7,2,9,0,8,3,9,3,8,5,2,7,1,8...
未定義種子的構造方法裏,使用當前系統時間相關的一個數字做爲種子數,該種子數只做爲隨機算法的起源數字,與生成的隨機數區間無關係算法
public Random() { this(seedUniquifier() ^ System.nanoTime()); } public Random(long seed) { if (getClass() == Random.class) this.seed = new AtomicLong(initialScramble(seed)); else { // subclass might have overriden setSeed this.seed = new AtomicLong(); setSeed(seed); } }