【问题标题】:Easy way to generate unique random numbers (range) using threads? Java使用线程生成唯一随机数(范围)的简单方法?爪哇
【发布时间】: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


【解决方案1】:

这是一个相当容易的任务。只需使用并发哈希图来防止重复。确保将边界 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

【讨论】:

    猜你喜欢
    • 2013-12-14
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    相关资源
    最近更新 更多