2016-03-04 72 views
0

我必須爲他們開發一個程序和一個類,它們必須通過名爲combinar(id)(id讓我們區分氧和氫)的方法接收來自原子的請求。「同步」不起作用

必須通過前面提到的申請創建的分子只能在最終存在2個互補時才能生成。原子並沒有一個(O case)或兩個(H case)原子在等待(在這種情況下,新的也應該等待)。

我的問題是該消息的 「分子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éculaformada」,但我不打印,@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分子的創建沒有任何O原子。 : - ?同步問題。 – garciacarmonaam