java Проблема простых чисел в многопоточности - PullRequest
0 голосов
/ 04 апреля 2020

Мой код выглядит так:

public class Demo {

   public static void main(String[] args) throws InterruptedException {
      primeGen prime = new primeGen(10, 50);

      Thread th1 = new Thread(prime);
      th1.setName("Thread1");

      Thread   th2 = new Thread(prime);
      th2.setName("Thread2");

      th1.start();
      th2.start();
   }
}

class primeGen implements Runnable {
   private int N1,N2;
   private volatile int i;

   public primeGen(int n1, int n2) {
        this.N1 = n1;
        this.N2 = n2;
        i = N1;
   }

   private boolean isPrime(int N) {
      for(int j = 2; j <= N / 2; j++) {
         if(0 == N % j) return false;
      }
      return true;
   }

   private void primeRange(int N1 , int N2){

      Thread th = Thread.currentThread();

      for(; i <= N2; i++) {

      if(isPrime(i))
        System.out.print(th.getName() + " " + i + " is prime \n");
      }
   }

   @Override
   public void run() {
      primeRange(N1 , N2);
   }
}

Токовый выход консоли:

  • Thread1 11 простое
  • Thread1 13 является простым
  • Thread2 13 является простым
  • Thread2 17 является простым
  • Thread2 19 является простым
  • Thread2 23 является простым
  • Thread2 29 простое
  • Thread2 31 простое
  • Thread2 37 простое
  • Thread2 41 простое
  • Thread2 43 простое
  • Thread2 47 является простым

Почему некоторые простые числа повторяются несколькими потоками и как я могу предотвратить это?

1 Ответ

1 голос
/ 04 апреля 2020

Синхронизируйте isPrime и primeRange, чтобы избежать одновременного доступа к ним более чем одного потока. Узнайте больше у здесь .

public class Demo {

    public static void main(String[] args) throws InterruptedException {
        primeGen prime = new primeGen(10, 50);
        Thread th1 = new Thread(prime);
        th1.setName("Thread1");
        Thread th2 = new Thread(prime);
        th2.setName("Thread2");
        th1.start();
        th2.start();
    }
}

class primeGen implements Runnable {
    private int N1, N2;
    private volatile int i;

    public primeGen(int n1, int n2) {
        this.N1 = n1;
        this.N2 = n2;
        i = N1;
    }

    private synchronized boolean isPrime(int N) {
        for (int j = 2; j <= N / 2; j++) {
            if (0 == N % j) {
                return false;
            }
        }
        return true;
    }

    private synchronized void primeRange(int N1, int N2) {
        Thread th = Thread.currentThread();
        for (; i <= N2; i++) {
            if (isPrime(i)) {
                System.out.print(th.getName() + " " + i + " is prime \n");
            }
        }
    }

    @Override
    public void run() {
        primeRange(N1, N2);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...