“同步”不起作用

时间:2016-03-04 17:41:03

标签: java multithreading concurrency

我必须为它们开发一个程序和一个类,它必须通过一个名为combinar(id)的方法接收来自原子的请求(id让我们区分氧和氢)。

必须通过前面提到的请求创建的分子,只有在最后存在时才能生成2个完整的。原子并没有一个(O case)或两个(H case)原子在等待(在这种情况下,new也应该等待)。

我的问题是创建了“Moléculaformada”消息,与价值无关

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 :(得分: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--;

为什么在调用wait之后立即增加atomosH_esperando不明确。在循环中调用wait的意思是在你进入循环之前条件可能是真的,或者你可以退出等待并发现条件仍然是假的,所以这里不应该有任何增量的计数器或任何其他取决于调用等待次数的逻辑。这个等待的另一个线程应该做任何需要完成的增量。