Java 锁定条件似乎无法正常工作

Java lock conditions seem to not be working right

我有一个问题,有 BoundedBufferConsumersProducers,生产者填充缓冲区,消费者从缓冲区中删除。

我正在为消费者和生产者使用线程,并且我试图使用锁定条件来确保缓冲区对生产者来说不是满的,对消费者来说不是空的。

不幸的是,它没有按照我想要的方式工作,似乎 Consumer/Producer,当它们在 Condition.await 时,不要让其他线程工作。他们不应该让他们吗?

这是我的代码


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) {}
        }
    }
}

提前致谢

不要将内部锁(意思是 synchronized)与可重入锁混合使用。此代码尝试获取内部锁,然后获取重入锁。

在实例方法上放置 synchronized 需要调用该方法的线程获取实例上的内部锁。 ReentrantLock 是一个单独的锁定结构,不使用该关键字。混合这两种机制是不必要的,只会造成麻烦。

(具体代码是在条件对象上调用 await,这导致线程释放可重入锁,但该线程一直持有内部锁,阻止其他线程进入同步方法。)

解决此问题的方法是从您的代码中删除 synchronized 关键字。