java - 不同实例的多线程仍然产生相同的结果,如何克服这个问题?
问题描述
public class MultiThreadingRandom {
public static void main(String[] args) throws InterruptedException {
MultiThreadingRandom multiThreadingRandom = new MultiThreadingRandom();
ExecutorService executorService = Executors.newFixedThreadPool(2);
geneRan r1= new geneRan();
geneRan r2= new geneRan();
executorService.submit(r1);
executorService.submit(r2);
executorService.shutdown();
}
}
class geneRan implements Runnable{
int rand_int1=0;
@Override
public void run() {
// TODO Implement this method
Random rand = new Random();
rand_int1 = rand.nextInt(1000);
System.out.println(rand_int1);
// System.out.println(ai.getAndIncrement());
}
}
该程序有时会给出 2 个不同的输出,但有时会给出相同的输出。
实际上,我对这 2 个线程使用了 2 个不同的对象,所以为什么在某些情况下它会给出相同的结果。
无论如何,我只传递了 2 个不同的对象,它的线程安全代码。那么我如何确保在任何情况下生成 2 个不同的随机数。
解决方案
正如已经评论过的,这与多线程无关。因为数字是随机的,所以它们也有可能是相同的。
如果你想要 2 个不一样的随机数,你可以这样做:
//Create List of integers
List<Integer> numberPool = new ArrayList<>();
//Initialize list with numbers from 1 to 1000
for(int num = 1; num <= 1000 ; num++) {
numberPool.add(num);
}
//Randomly shuffle list
Collections.shuffle(numberPool);
//Get first number
System.out.println(numberPool.get(0));
//Get second number
System.out.println(numberPool.get(1));
如果你想以多线程方式访问 numberPool,你可以这样做:
public class NumGeneratorThreadSafe{
List<Integer> numberPool = new ArrayList<>();
private int counter = 0;
public NumGeneratorThreadSafe() {
for(int i = 1; i <= 1000 ; i++) {
this.numberPool.add(i);
}
Collections.shuffle(this.numberPool);
}
public synchronized Integer getRandomNumber() {
return this.numberPool.get(this.counter++);
}
public synchronized void resetCounter() {
this.counter = 0;
}
}
希望这可以帮助。
编辑: 为了在线程中使用类:
public class MultiThreadingRandom {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
NumGeneratorThreadSafe numGenerator = new NumGeneratorThreadSafe();
GeneRan r1 = new GeneRan(numGenerator);
GeneRan r2 = new GeneRan(numGenerator);
executorService.submit(r1);
executorService.submit(r2);
executorService.shutdown();
}
}
class GeneRan implements Runnable{
private NumGeneratorThreadSafe numGenerator;
public GeneRan(NumGeneratorThreadSafe numGenerator) {
this.numGenerator = numGenerator;
}
@Override
public void run() {
int randInt = this.numGenerator.getRandomNumber();
System.out.println(randInt);
}
}
推荐阅读
- kotlin - Refcount Observable 不会在第二次订阅时发出
- python - Django 使用外键添加到数据库,同时仍显示来自其他模型的信息
- php - 删除 OceanWP 主题中产品页面标题下的子标题文本
- jquery - 带有附加数据的标签中声明的 jQuery 触发事件
- python - 无法从购物车页面-django url 错误访问我的在线商店的订单页面
- solr - Solr Cloud - Solr 挂起/无法启动或无法完全创建集合:
- reactjs - React fetch 有错误 fetch 被 CORS 策略阻止
- ruby-on-rails - Rails 嵌套资源显示两次.. 一次在开始,一次在结束
- c++ - 使用 Matlab C++ 编译器将 C++ 代码转换为 Matlab
- php - 如何在引导程序中将 mysql 表记录显示为导航