condiciones de bloqueo de Java parece que no está funcionando satisfactoriamente

Manuel0Borba :

Tengo un problema en el que hay una BoundedBuffery hay Consumersy Producers, los productores llenan el búfer y los consumidores eliminar de la memoria intermedia.

Estoy usando hilos para los consumidores y productores, y yo estaba tratando de utilizar las condiciones de bloqueo para asegurar que el buffer no está lleno al productor y no está vacía para el consumidor.

Por desgracia no está funcionando de la manera que quería, parece que el consumidor / productor, cuando están en Condition.await, no deje que la otra obra hilos. ¿No deberían dejar que ellos?

Aquí está mi código


class main
{
    public static void main (String[] args) throws InterruptedException
    {
        final int N = Integer.parseInt(args[0]); 
        BoundedBuffer teste = new BoundedBuffer(N);
        Thread c = new Consumidor(teste,N);
        Thread p = new Produtor(teste,N);
        c.start();
        p.start();
        c.join();
        p.join();
    }
}

class BoundedBuffer
{
    ArrayList<Integer> array;
    int index;
    int size;

    Lock l = new ReentrantLock();
    Condition notFull = l.newCondition();
    Condition notEmpty = l.newCondition();

    BoundedBuffer(int N)
    {
        this.array=new ArrayList<Integer>(N);
        this.index = 0;
        this.size=N;
    }

    public synchronized void put(int e) throws InterruptedException 
    {
        l.lock();
        try
        {
            while(this.index >= this.size)
            {
                notFull.await();
            }
            this.array.add(index,e);
            this.index++;
            notEmpty.signal();
        }
        finally
        {
            l.unlock();
        }       
    }

    public synchronized int get() throws InterruptedException 
    {
        int i;
        l.lock();
        try
        {   
            while(this.index <=0)
            {           
                notEmpty.await();
            }
            this.index--;
            notFull.signal();
            i = this.array.get(index);
        }
        finally
        {
            l.unlock();
        }
         return i;

    }
}

class Consumidor extends Thread
{
    private BoundedBuffer b;
    final int j;
    public Consumidor(BoundedBuffer b, int j)
    {
        this.b = b;
        this.j=j;
    }
    public void run() 
    { 
        int a;
        for (int i = 0; i < j ;++i)
        {  
            try
            {  
                a=b.get();
                System.out.println("GET: " +a); 
            }
            catch (Exception e) {}
        }
    }
}


class Produtor extends Thread
{
    private BoundedBuffer b;
    final int j;
    public Produtor(BoundedBuffer b, int j)
    {
        this.b = b;
        this.j=j;
    }
    public void run() 
    { 
        int a;
        for (int i = 0; i < j; ++i)
        {   
            try
            { 
                b.put(i);
                System.out.println("PUT: " +i);
            }
            catch (Exception e) {}
        }
    }
}

Gracias por adelantado

Nathan Hughes:

No mezcle cerraduras intrínsecas (significado synchronized) con reentrantLocks. Este código está tratando de adquirir el bloqueo intrínseco y entonces el ReentrantLock.

Poner synchronizeden un método de instancia requiere que el hilo de llamar al método para adquirir el bloqueo intrínseco en la instancia. ReentrantLock es una construcción de bloqueo separada que no utilice esa palabra clave. La mezcla de los dos mecanismos es innecesario y sólo puede causar problemas.

(Específicamente, el código está llamando esperan en el objeto de condición, que hace que el hilo para liberar el bloqueo de reentrada, pero el hilo mantiene sostiene sobre el bloqueo intrínseco, evitando que el otro hilo de entrar en un método sincronizado.)

La solución a esto es para eliminar la synchronizedpalabra clave de su código.

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=394605&siteId=1
Recomendado
Clasificación