user1742919
user1742919

Reputation: 401

MultiThreading of Different Instances still producing same results, how to overcome this?

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

This program gives 2 different outputs sometimes, but sometimes its giving same the output.

Actually I'm using 2 different objects to these 2 threads so why its giving same results in some cases.

Anyway i'm passing 2 different objects its Thread Safety code only. Then how i can be assure to generate 2 different random numbers at any case.

Upvotes: 1

Views: 72

Answers (2)

ieggel
ieggel

Reputation: 961

As already commented, this has nothing to do with multithreading. Because the numbers are random, there is also a chance they can be the same.

If you want 2 random numbers that are not the same, you could do something like this:

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

If you want to access the numberPool in a multithreaded fashion, you can do something like that:

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

}

Hope this helps.

EDIT : In order to use the class in threads:


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

Upvotes: 1

kosta.dani
kosta.dani

Reputation: 457

how about this

import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MultiThreadingRandom {
   public static void main(String[] args) throws InterruptedException, ExecutionException {
      ExecutorService executorService = Executors.newFixedThreadPool(2);
      Generun r1 = new Generun();
      executorService.submit(r1);
      Thread.sleep(100);
      executorService.submit(r1);
      executorService.shutdown();

   }
}

class Generun implements Runnable {
   int nextInt = -1;
   int bound = 1000;

   @Override
   public void run() {
      int temp = nextInt;

      nextInt = new Random().nextInt(bound);

      if (temp == nextInt) {
         do {
            nextInt = new Random().nextInt(bound);
         } while (temp == nextInt);
      }
      System.out.println(nextInt);
   }
}

Upvotes: 1

Related Questions