2016-03-04 76 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