2016-03-04 3 views
0

Мне нужно разработать программу и класс для них, которые должны получать запросы от атомов с помощью метода combinar (id) (идентификация между кислородом и водородом).«Синхронизированный» не работает

Молекула, которая должна быть создана по предыдущим петициям, может генерироваться только тогда, когда, наконец, существует 2 дополнения. атомов, и нет ни одного (O-case), либо двух (H случайных) атомов, ожидающих (в этом случае новый тоже должен ждать).

Моя проблема заключается в том, что сообщение "Молекула formada" создается также, независимо от значений

public class Aire { 

    int atomosHidrogeno = 0; 
    int atomosOxigeno = 0; 
    int atomosH_esperando; 
    int atomosO_esperando; 

    public Aire(int atH, int atO2) { 
     this.atomosHidrogeno = atH; 
     this.atomosOxigeno = atO2; 
     this.atomosH_esperando = 0; 
     this.atomosO_esperando = 0; 
    } 

    public void combinar(int id) { 
     if (id == 0) // Hidrogeno 
     { 
      synchronized (this) { 
       while (this.atomosH_esperando == 2 || (this.atomosHidrogeno < 1 && this.atomosOxigeno < 0)) { 
        try { 
         wait(); 
         this.atomosH_esperando++; 
        } catch (InterruptedException ie) { 
        } 
       } 
       notifyAll(); 
      } 
      this.atomosH_esperando--; 
      System.out.println("Molécula formada"); 
     } else if (id == 1) // Oxigeno 
     { 
      synchronized (this) { 
       while (this.atomosO_esperando == 1 || (this.atomosHidrogeno < 2)) { 
        try { 
         wait(); 
         this.atomosO_esperando++; 
        } catch (InterruptedException ie) { 
        } 
       } 
       notifyAll(); 
      } 
      this.atomosO_esperando--; 
      System.out.println("Molécula formada"); 
     } 
    } 
} 

Это мое использование класса:

public class Principal { 

    public static void main(String[] args) { 

     Aire aire = new Aire(0, 0); 

     Atomo[] atomos_ = new Atomo[3]; 
     Atomo[] atomos__ = new Atomo[3]; 
     Atomo[] atomos___ = new Atomo[3]; 

     for (int i = 0; i < 3; i++) 
     { 
      atomos_[i] = new Atomo(aire,0); 
      atomos_[i].start(); 
     } 

     for (int i = 0; i < 3; i++) 
     { 
      atomos__[i] = new Atomo(aire,1); 
      atomos__[i].start(); 
     } 

     for (int i = 0; i < 3; i++) 
     { 
      atomos___[i] = new Atomo(aire,0); 
      atomos___[i].start(); 
     } 
    } 
} 
public class Atomo extends Thread { 
    private int id = 0; 
    Aire aire; 

    public Atomo(Aire aire, int id) { 
     this.id = id; 
     this.aire = aire; 
    } 

    public void run() { 
     this.aire.combinar(this.id); 
    } 
} 
+1

Опишите, как вы ожидаете, что ваш код будет вести себя и что именно «* не работает». –

+0

Правда, сообщение «Molécula formada», но я также не печатаю, @fabian – garciacarmonaam

+2

Обратите внимание, что вы уменьшаете переменные '* _esperando' вне синхронизированного блока, который не является потокобезопасным. Возможно, вы захотите переместить их внутри синхронизированных блоков. –

ответ

0

Выполнение инкремента вне синхронизированного блока небезопасно, так как Andy указывает на комментарий. Но более того, поведение ждет не имеет смысла:

 synchronized (this) { 
      while (this.atomosH_esperando == 2 || (this.atomosHidrogeno < 1 && this.atomosOxigeno < 0)) { 
       try { 
        wait(); 
        this.atomosH_esperando++; 
       } catch (InterruptedException ie) { 
       } 
      } 
      notifyAll(); 
     } 
     this.atomosH_esperando--; 

Почему вы увеличиваете atomosH_esperando сразу после звонка ждать непонятно. Точка ожидания ожидания в цикле заключается в том, что условие может быть истинным до того, как вы войдете в цикл, или вы можете выйти из ожидания и найти условие по-прежнему ложным, поэтому не должно быть никакого приращения счетчика здесь или любого другого логика, зависящая от того, сколько раз вызывается ожидание. Другой поток, который ожидает этого, должен делать любое увеличение, которое необходимо выполнить.

+0

Спасибо за решение, но хотя я могу считать новый атом, иногда некоторые молекулы H2O создаются без какого-либо атома О. : -? Проблемы синхронизации. – garciacarmonaam

Смежные вопросы