java - 使用线程生成唯一随机数(范围)的简单方法?爪哇
问题描述
我想使用 Java 中的线程从给定的输入范围生成唯一随机数列表。例如,给定 1-4 的范围,我会运行 4 个线程,每个线程会生成一个随机数,这样没有两个线程会两次产生相同的值。我想我需要实现一些同步或什么?我试过使用Join()
,但它似乎不起作用。
我的构造函数使用输入值来填充具有给定范围的数组列表。在 run 方法中,我生成一个随机值(来自同一范围)并检查它是否在列表中。如果是,我将其从列表中删除并打印该值。这个想法是当另一个线程进来时,它不能再次生成相同的值。
这是我到目前为止所拥有的:
public class Main {
public static void main(String[] args) {
randomThreadGen randomRange = new randomThreadGen(1, 2);
Thread thread1 = new Thread(randomRange);
Thread thread2 = new Thread(randomRange);
thread1.start();
try {
thread1.join();
} catch (InterruptedException e) {
}
thread2.start();
}
}
和这个:
public class randomThreadGen implements Runnable {
private int lowerBound;
private int upperBound;
private final ArrayList<Integer> List = new ArrayList<Integer>();
public randomThreadGen(int lowerb, int upperb) {
this.lowerBound = lowerb;
this.upperBound = upperb;
for (int i = lowerb; i < upperb + 1; i++) { // populate list with values based on lower and upperbounds specified from main
List.add(i);
}
}
@Override
public void run() {
// generate random value
// check if in list. If in list, remove it
// print value
// otherwise try again
int val = ThreadLocalRandom.current().nextInt(lowerBound, upperBound+1); // generate random value based on lower and upper bound inputs from main
while(true){
if(List.contains(val)){
List.remove(new Integer(val));
System.out.println("Random value for " + Thread.currentThread().getName() + " " + val);
System.out.println("List values: " + List);
}
break;
}
}
}'''
这个低范围的测试用例是为了使测试变得容易。有时它会起作用,Thread0 会生成与 Thread01 不同的值(例如 1 和 2 或 2 和 1)。但有时它不会(似乎它们生成相同的值,在这种情况下我的代码只打印一个值)例如,“Thread02 1”,仅此而已。
有任何想法吗?除了 有没有其他方法可以做到这一点join()
?
解决方案
这是一个很容易的任务。只需使用并发哈希图来防止重复。确保将边界 int 和 hashmap 声明为 final。需要 Thread.join 以保证在所有线程完成工作后打印结果。还有其他有效的技术可以代替 join,但它们不适合新手。
尝试这个:
import java.util.concurrent.ThreadLocalRandom;
import java.util.*;
import java.util.concurrent.*;
public class Main {
final static int low = 0;
final static int up = 5;
final static Set < Integer > inthashmap = ConcurrentHashMap.newKeySet();
// threadhashmap is needed to track down all threads generating ints
final static Set < Thread > threadhashmap = ConcurrentHashMap.newKeySet();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < up - low + 1; i++) {
Thread t = new Thread() {
public void run() {
int randomNum;
try {
randomNum = ThreadLocalRandom.current().nextInt(low, up + 1);
inthashmap.add(randomNum);
System.out.println("A new random int generated : " + randomNum);
} finally {
}
}
};
threadhashmap.add(t);
t.start();
}
//by iterating through all threads in threadhashmap
// and joining them we guarantee that all threads were completed
// before we print the results of work of those threads (i.e. ints)
Iterator<Thread> iterator = threadhashmap.iterator();
while (iterator.hasNext())
iterator.next().join();
System.out.println("Unique ints from hashmap:");
inthashmap.forEach(System.out::println);
}
}
输出:
A new random int generated : 2
A new random int generated : 3
A new random int generated : 3
A new random int generated : 0
A new random int generated : 0
A new random int generated : 2
Unique ints from hashmap:
0
2
3
推荐阅读
- node.js - Mongo $group 划分两个字段并显示结果
- sql - 如何在 PostgreSQL 的同一查询中使用两个 SUM() 聚合函数?
- sql - 用于在表中显示姓名和部门的 SQL 查询
- bash - 用 sed 中的文件内容替换字符串
- c - 从 int 数组中取出前三个(或所需数量),将它们存储到一个新的临时数组中,同时删除 OG 数组中的这 3 个。
- python - 需要根据出现频率替换 Pandas 中的值
- powershell - PowerShell - 用于在文件内容中搜索关键字的脚本
- facebook - 是否可以在不将用户登录到 Facebook 的情况下使用 Facebook Unity SDK 跟踪应用安装?
- javascript - 如何在 javascript 中对非数组进行排序?
- c++ - 使用返回模板声明接口的 C++ 错误