首页 > 解决方案 > 不同实例的多线程仍然产生相同的结果,如何克服这个问题?

问题描述

     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 个不同的随机数。

标签: java

解决方案


正如已经评论过的,这与多线程无关。因为数字是随机的,所以它们也有可能是相同的。

如果你想要 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);
      }
}

推荐阅读