简体   繁体   English

使用线程生成唯一随机数(范围)的简单方法? 爪哇

[英]Easy way to generate unique random numbers (range) using threads? Java

I want to generate a list of unique random numbers from a given input range using threads in Java.我想使用 Java 中的线程从给定的输入范围生成唯一随机数列表。 For example, given a range of 1-4, I would run 4 threads and each thread would generate a random number such that no two threads would produce the same value twice.例如,给定 1-4 的范围,我将运行 4 个线程,每个线程将生成一个随机数,这样没有两个线程会产生两次相同的值。 I presume I need to implement some synchronization or something?我想我需要实现一些同步或什么? I've tried using Join() but it doesn't seem to work.我试过使用Join()但它似乎不起作用。

My constructor uses input values to populate an array list with a given range.我的构造函数使用输入值来填充具有给定范围的数组列表。 In the run method, I generate a random value (from the same range) and check if it's in the list.在 run 方法中,我生成一个随机值(来自相同范围)并检查它是否在列表中。 If it is, I remove it from the list and print the value.如果是,我将其从列表中删除并打印该值。 The idea is that when another thread comes in, it can't generate that same value again.这个想法是当另一个线程进入时,它不能再次生成相同的值。

Here is what I have so far:这是我到目前为止所拥有的:

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();
}
}

And this:和这个:

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;
        
    }
    
    }
}'''

This test case with a low range is to make testing easy.这个低范围的测试用例是为了让测试变得容易。 Sometimes it works, and Thread0 will generate a different value to Thread01 (1 and 2 or 2 and 1 for example).有时它会起作用,并且 Thread0 将生成与 Thread01 不同的值(例如 1 和 2 或 2 和 1)。 But sometimes it doesn't (seemingly they generate the same value, in which case my code only prints one value) For example, "Thread02 1" and nothing else.但有时它不会(似乎它们生成相同的值,在这种情况下我的代码只打印一个值)例如,“Thread02 1”,没有别的。

Any ideas?有任何想法吗? Is there another way to do this other than join() ?除了join()之外,还有其他方法可以做到这一点吗?

It's quite an easy task.这是一个很容易的任务。 Just use a concurrent hashmap to prevent duplicates.只需使用并发哈希图来防止重复。 Make sure to declare boundary int and the hashmap as final.确保将boundary int 和hashmap 声明为final。

Try this:尝试这个:

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);
    }
}

Output:输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM