Какие изменения мне следует сделать в этом коде, чтобы два потока go до конца массива и распечатали все его содержимое - PullRequest
0 голосов
/ 13 июля 2020

Я пытаюсь напечатать все числа в массиве, начиная с 1 с индексом 0 и заканчивая наконец 11. Есть два потока, которые делают это: один печатает только четное число, а второй печатает только нечетные числа.

Вот код.

class PrintEvenOdd {
      
    static class SourceData {
      
         int[] arr;
         volatile int counter;

         public SourceData(int[] commonArr, int counter){
           
             this.arr = commonArr;
             this.counter = counter;
         }

         public void getData(){
           try{
             synchronized(this){
                    
                 while((counter%2==0 && Thread.currentThread().getName().equalsIgnoreCase("odd")) || (counter%2!=0 && Thread.currentThread().getName().equalsIgnoreCase("even"))){
                    wait();
                 }

                 System.out.println(counter+ " : " + Thread.currentThread().getName());

                 notify();
             }
           }catch(Exception ie){
              ie.printStackTrace();
           }
         }

    }

    static class Even extends Thread{
      SourceData sd;

      public Even(SourceData sd){
          this.sd = sd;        
      }

      @Override
      public void run(){
        while(sd.counter < 12) {   
         sd.getData();
         sd.counter++;
        }
      }
    }

    static class Odd extends Thread{
      SourceData sd;
      

      public Odd(SourceData sd){
         this.sd = sd;
      }

      @Override
      public void run(){
        while(sd.counter < 12) {  
         sd.getData();
         sd.counter++;
        }
      }
    }

    public static void main(String[] args){
       int[] commonArr = new int[11];
       for(int i = 0; i < commonArr.length; i++){
         commonArr[i] = i;  
       }
       int counter = 0;
   
       SourceData sd = new SourceData(commonArr, counter);
         Even even = new Even(sd);
         even.setName("EVEN");
         even.start();
         Odd odd = new Odd(sd);
         odd.setName("ODD");
         odd.start();
    }
}

Проблема с этим кодом что он печатает только два значения, показанные здесь:

0 : EVEN
1 : ODD

Какие изменения мне следует сделать, чтобы код печатал все значения до конца массива?

1 Ответ

1 голос
/ 13 июля 2020

Вот что происходит: запускается EVEN, счетчик увеличивается до 1, а затем в следующем getData начинается ожидание. Затем запускается ODD, увеличивает счетчик до 2, а затем тоже начинает ждать в getData. У вас есть два потока, ожидающих без шансов на пробуждение.

Чтобы исправить это, вы должны уведомить, когда условие, в котором поток ожидает изменений. То есть: уведомить после sd.counter++, чтобы другой поток мог проснуться. Поскольку другой поток ожидает sd, вы должны вызвать:

sd.counter++
sd.notify()

Также обратите внимание, что потоки ODD и EVEN идентичны. Вы можете иметь один класс, реализующий поток, и создавать его два экземпляра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...