Java:在指定的范圍內(nèi)生成指定數(shù)量的隨機數(shù)

          需求:我們需要在三個不同的數(shù)字段產(chǎn)生不同數(shù)量的隨機數(shù)。

          比如:[0, 10) 6個;[10, 20) 2個;[20, 30) 2個。

          以下為測試代碼:


           1 package com.homeland.myapp;
           2 
           3 import java.util.Random;
           4 
           5 
           6 public class RandomSequence {
           7 
           8     public static void main(String[] args) {
           9         RandomGen d1 = new RandomGen(0106);
          10         RandomGen d2 = new RandomGen(10202);
          11         RandomGen d3 = new RandomGen(20302);
          12         Thread t1 = new Thread(d1);
          13         Thread t2 = new Thread(d2);
          14         Thread t3 = new Thread(d3);
          15         t1.start();
          16         t2.start();
          17         t3.start();
          18     }
          19 
          20 }
          21 
          22 class RandomGen implements Runnable {
          23     Random r = new Random();
          24     int start, end, num;
          25     
          26     public RandomGen(int end) {
          27         this.end = end;
          28     }
          29     
          30     public RandomGen(int start, int end) {
          31         this.start = start;
          32         this.end = end;
          33     }
          34     
          35     public RandomGen(int start, int end, int num) {
          36         this.start = start;
          37         this.end = end;
          38         this.num = num;
          39     }
          40     
          41     @Override
          42     public void run() {
          43         int c = 0;
          44         for (int i = 0; c < num; i++) {
          45             int a = r.nextInt(end);
          46             if (a >= start) {
          47                 System.out.println("Number " + i + " is: " + a);
          48                 c++;
          49             }
          50         }
          51         System.out.println("-----------------------");
          52     }
          53 }

          以上三個不同的數(shù)字段都只包括第一個數(shù)字,不包括最后一個。也即,不包含上限。

          以下為測試結果:


           1 Number 0 is: 1
           2 Number 1 is: 5
           3 Number 2 is: 0
           4 Number 3 is: 7
           5 Number 4 is: 6
           6 Number 5 is: 8
           7 -----------------------
           8 Number 12 is: 26
           9 Number 13 is: 28
          10 -----------------------
          11 Number 0 is: 10
          12 Number 4 is: 11
          13 -----------------------
          考慮到去掉重復的數(shù)字,代碼作如下修改:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 
           8 public class RandomSequence {
           9 
          10     public static void main(String[] args) {
          11         RandomGen d1 = new RandomGen(0106);
          12         RandomGen d2 = new RandomGen(10202);
          13         RandomGen d3 = new RandomGen(20302);
          14         Thread t1 = new Thread(d1);
          15         Thread t2 = new Thread(d2);
          16         Thread t3 = new Thread(d3);
          17         t1.start();
          18         t2.start();
          19         t3.start();
          20     }
          21 
          22 }
          23 
          24 class RandomGen implements Runnable {
          25     Random r = new Random();
          26     int start, end, num;
          27     
          28     public RandomGen(int end) {
          29         this.end = end;
          30     }
          31     
          32     public RandomGen(int start, int end) {
          33         this.start = start;
          34         this.end = end;
          35     }
          36     
          37     public RandomGen(int start, int end, int num) {
          38         this.start = start;
          39         this.end = end;
          40         this.num = num;
          41     }
          42     
          43     @Override
          44     public void run() {
          45         Set<Integer> s = new HashSet<Integer>();
          46         for (int i = 0; s.size() < num; i++) {
          47             int a = r.nextInt(end);
          48             if (a >= start) {
          49                 s.add(a);
          50             }
          51         }
          52         System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          53         System.out.println(s.toString());
          54         System.out.println("-----------------------");
          55     }
          56 }
          其中一組結果如下:

           1 there are 6 numbers in range: [010]:
           2 
           3 [025689]
           4 -----------------------
           5 there are 2 numbers in range: [2030]:
           6 
           7 [2226]
           8 -----------------------
           9 there are 2 numbers in range: [1020]:
          10 
          11 [1113]
          12 -----------------------
          13 
          我修改了代碼,在某個位置上加入了syncronized關鍵字,還有用循環(huán)來控制線程的產(chǎn)生:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20         }
          21     }
          22 
          23 }
          24 
          25 class RandomGen implements Runnable {
          26     Random r = new Random();
          27     int start, end, num;
          28     Set<Integer> s = new HashSet<Integer>();
          29     
          30     public RandomGen(int end) {
          31         this.end = end;
          32     }
          33     
          34     public RandomGen(int start, int end) {
          35         this.start = start;
          36         this.end = end;
          37     }
          38     
          39     public RandomGen(int start, int end, int num) {
          40         this.start = start;
          41         this.end = end;
          42         this.num = num;
          43     }
          44     
          45     @Override
          46     public void run() {
          47         synchronized (s) {
          48             for (int i = 0; s.size() < num; i++) {
          49                 int a = r.nextInt(end);
          50                 if (a >= start) {
          51                     s.add(a);
          52                 }
          53             }
          54             System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          55             System.out.println(s.toString());
          56             System.out.println("-----------------------");
          57         }// sync
          58     }
          59 }
          但是,我得到如下結果:

           1 there are 4 numbers in range: [2030]:
           2 
           3 there are 3 numbers in range: [3040]:
           4 
           5 [353930]
           6 -----------------------
           7 there are 6 numbers in range: [010]:
           8 
           9 [012679]
          10 -----------------------
          11 there are 2 numbers in range: [1020]:
          12 
          13 [1612]
          14 -----------------------
          15 there are 7 numbers in range: [5060]:
          16 
          17 [51505553525958]
          18 -----------------------
          19 [21202426]
          20 -----------------------
          21 there are 9 numbers in range: [7080]:
          22 
          23 [707176777972737475]
          24 -----------------------
          25 there are 5 numbers in range: [4050]:
          26 
          27 [4843404645]
          28 -----------------------
          29 there are 7 numbers in range: [90100]:
          30 
          31 [98999693959490]
          32 -----------------------
          33 there are 8 numbers in range: [6070]:
          34 
          35 [6869646566676260]
          36 -----------------------
          37 there are 4 numbers in range: [8090]:
          38 
          39 [84878389]
          40 -----------------------
          看起來某些部分的輸出時交錯的。看來我需要另外一種控制機制。

          這個控制機制就是:


          1 Thread.sleep(5000);
          把這句放到上面代碼中的main()方法的循環(huán)中去。

          上面的Thread.sleep(5000)不是沒有問題的。你可以試想一下,如果數(shù)字的范圍很大呢?

          所以,問題的關鍵是:如何保證線程同步或者說線程對共享資源的互斥訪問呢?把代碼做如下修改:


           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) throws Exception {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20             Thread.sleep(1);
          21         }
          22     }
          23 
          24 }
          25 
          26 class RandomGen implements Runnable {
          27     Random r = new Random();
          28     int start, end, num;
          29     private Set<Integer> s = new HashSet<Integer>();
          30     private static Object lock = new Object();
          31     
          32     public RandomGen(int end) {
          33         this.end = end;
          34     }
          35     
          36     public RandomGen(int start, int end) {
          37         this.start = start;
          38         this.end = end;
          39     }
          40     
          41     public RandomGen(int start, int end, int num) {
          42         this.start = start;
          43         this.end = end;
          44         this.num = num;
          45     }
          46     
          47     
          48     @Override
          49     public void run() {
          50         synchronized (lock) {
          51             for (int i = 0; s.size() < num; i++) {
          52                 int a = r.nextInt(end);
          53                 if (a >= start) {
          54                     s.add(a);
          55                 }
          56             }
          57             System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          58             System.out.println(s.toString());
          59             System.out.println("-----------------------");
          60         }// sync
          61     }
          62 }
          你木有看錯!靜態(tài)類成員被所有類實例共享。關鍵的一句:

          1 private static Object lock = new Object();
          當然,你也可以這么改:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) throws Exception {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20             Thread.sleep(1);
          21         }
          22     }
          23 
          24 }
          25 
          26 class RandomGen implements Runnable {
          27     static final Random r = new Random();
          28     static int start, end, num;
          29     private static Set<Integer> s = new HashSet<Integer>();
          30     
          31     public RandomGen(int end) {
          32         this.end = end;
          33     }
          34     
          35     public RandomGen(int start, int end) {
          36         this.start = start;
          37         this.end = end;
          38     }
          39     
          40     public RandomGen(int start, int end, int num) {
          41         this.start = start;
          42         this.end = end;
          43         this.num = num;
          44     }
          45     
          46     private static synchronized void printSequence() {
          47         for (int i = 0; s.size() < num; i++) {
          48             int a = r.nextInt(end);
          49             if (a >= start) {
          50                 s.add(a);
          51             }
          52         }
          53         System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          54         System.out.println(s.toString());
          55         System.out.println("-----------------------");
          56     }
          57     
          58     @Override
          59     public void run() {
          60         printSequence();
          61     }
          62 }
          需要注意下,后面的靜態(tài)方法會產(chǎn)生類似這樣的結果:

           1 there are 2 numbers in range: [1020]:
           2 
           3 [183]
           4 -----------------------
           5 there are 4 numbers in range: [2030]:
           6 
           7 [1832023]
           8 -----------------------
           9 there are 4 numbers in range: [2030]:
          10 
          11 [1832023]
          12 -----------------------
          13 there are 3 numbers in range: [3040]:
          14 
          15 [1832023]
          16 -----------------------
          17 there are 5 numbers in range: [4050]:
          18 
          19 [183202342]
          20 -----------------------
          21 there are 7 numbers in range: [5060]:
          22 
          23 [1832023425857]
          24 -----------------------
          25 there are 8 numbers in range: [6070]:
          26 
          27 [183652023425857]
          28 -----------------------
          29 there are 9 numbers in range: [7080]:
          30 
          31 [18365202376425857]
          32 -----------------------
          33 there are 4 numbers in range: [8090]:
          34 
          35 [18365202376425857]
          36 -----------------------
          37 there are 7 numbers in range: [90100]:
          38 
          39 [18365202376425857]
          40 -----------------------
          41 
          所以,你需要這么修改代碼:

           1 package com.homeland.myapp;
           2 
           3 import java.util.HashSet;
           4 import java.util.Random;
           5 import java.util.Set;
           6 
           7 public class RandomSequence {
           8 
           9     public static void main(String[] args) throws Exception {
          10         
          11         int a[][] = {
          12                 {0106}, {10202}, {20304}, 
          13                 {30403}, {40505}, {50607}, 
          14                 {60708}, {70809}, {80904}, {901007}};
          15         
          16         for (int i = 0; i < a.length; i++) {
          17             RandomGen d = new RandomGen(a[i][0], a[i][1], a[i][2]);
          18             Thread t = new Thread(d);
          19             t.start();
          20             Thread.sleep(1);
          21         }
          22     }
          23 
          24 }
          25 
          26 class RandomGen implements Runnable {
          27     static final Random r = new Random();
          28     int start, end, num;
          29     
          30     public RandomGen(int end) {
          31         this.end = end;
          32     }
          33     
          34     public RandomGen(int start, int end) {
          35         this.start = start;
          36         this.end = end;
          37     }
          38     
          39     public RandomGen(int start, int end, int num) {
          40         this.start = start;
          41         this.end = end;
          42         this.num = num;
          43     }
          44     
          45     private static synchronized void printSequence(int start, int end, int num) {
          46         final Set<Integer> s = new HashSet<Integer>();
          47         for (; s.size() < num;) {
          48             int a = r.nextInt(end);
          49             if (a >= start) {
          50                 s.add(a);
          51             }
          52         }
          53         System.out.println("there are "+ num +" numbers in range: [" + start + "" + end + "]:\n");
          54         System.out.println(s.toString());
          55         System.out.println("-----------------------");
          56     }
          57     
          58     @Override
          59     public void run() {
          60         printSequence(start, end, num);
          61     }
          62 }
          我得到的結果類似這種:

           1 there are 6 numbers in range: [010]:
           2 
           3 [034678]
           4 -----------------------
           5 there are 2 numbers in range: [1020]:
           6 
           7 [1713]
           8 -----------------------
           9 there are 4 numbers in range: [2030]:
          10 
          11 [20252628]
          12 -----------------------
          13 there are 3 numbers in range: [3040]:
          14 
          15 [333830]
          16 -----------------------
          17 there are 5 numbers in range: [4050]:
          18 
          19 [4340464745]
          20 -----------------------
          21 there are 7 numbers in range: [5060]:
          22 
          23 [55545359585756]
          24 -----------------------
          25 there are 8 numbers in range: [6070]:
          26 
          27 [6869646663626160]
          28 -----------------------
          29 there are 9 numbers in range: [7080]:
          30 
          31 [707176777879727374]
          32 -----------------------
          33 there are 4 numbers in range: [8090]:
          34 
          35 [86808288]
          36 -----------------------
          37 there are 7 numbers in range: [90100]:
          38 
          39 [96979392959490]
          40 -----------------------
          41 
          留個小尾巴:用HashSet去重效率如何呢?

          posted on 2014-05-15 16:05 馬克思.佩恩 閱讀(196) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          <2014年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導航

          統(tǒng)計

          留言簿

          隨筆檔案

          文章分類

          相冊

          搜索

          最新評論

          主站蜘蛛池模板: 桂平市| 左贡县| 阿克陶县| 汪清县| 镇安县| 水富县| 即墨市| 福泉市| 库车县| 惠安县| 吴忠市| 天气| 定襄县| 平邑县| 台州市| 安顺市| 沾益县| 东丰县| 怀安县| 万荣县| 望谟县| 平顶山市| 浦城县| 化隆| 汉寿县| 吴桥县| 三台县| 辉南县| 新兴县| 高青县| 松潘县| 牡丹江市| 宝坻区| 崇仁县| 玉溪市| 建水县| 平安县| 竹北市| 泰顺县| 屏南县| 龙江县|