Java:在指定的范围内生成指定数量的随机数

需求:我们需要在三个不同的数字段产生不同数量的随机数。

比如:[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 }

以上三个不同的数字段都只包括第一个数字,不包括最后一个。也即,不包含上限。

以下为测试结果:


 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 -----------------------
考虑到去掉重复的数字,代码作如下修改:

 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关键字,还有用循环来控制线程的产生:

 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()方法的循环中去。

上面的Thread.sleep(5000)不是没有问题的。你可以试想一下,如果数字的范围很大呢?

所以,问题的关键是:如何保证线程同步或者说线程对共享资源的互斥访问呢?把代码做如下修改:


 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 }
你木有看错!静态类成员被所有类实例共享。关键的一句:

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 }
需要注意下,后面的静态方法会产生类似这样的结果:

 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 马克思.佩恩 阅读(198) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 
<2014年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

导航

统计

留言簿

随笔档案

文章分类

相册

搜索

最新评论