【发布时间】:2021-12-03 23:50:22
【问题描述】:
我想使用 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(),还有其他方法吗?
【问题讨论】:
-
您必须将并发集合添加到类处理线程的状态中,以确保没有重复的数字。
-
另一种方法是为每个线程提供不同的数字范围,例如线程 1 将从 [0,2} 生成数字,线程 2 从 [2,4} 生成数字
-
为什么?您不需要 4 个线程来生成 4 个随机数。这是矫枉过正。
标签: java multithreading thread-safety java-threads thread-synchronization