【问题标题】:Java lock conditions seem to not be working rightJava 锁定条件似乎无法正常工作
【发布时间】:2020-07-13 17:09:54
【问题描述】:

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

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

不幸的是,它没有按我想要的方式工作,似乎消费者/生产者在 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) {}
        }
    }
}

提前致谢

【问题讨论】:

  • 当我运行它时,它并没有完成程序,它停在 notEmpty.await(),它应该让生产者负责并插入项目,但它停在消费者处

标签: java multithreading conditional-statements locks


【解决方案1】:

不要将内在锁(即synchronized)与可重入锁混用。这段代码试图获取内在锁,然后是重入锁。

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

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

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

【讨论】:

    猜你喜欢
    • 2010-10-18
    • 2022-01-10
    • 2017-09-04
    • 2012-05-06
    • 2013-02-17
    • 2017-10-09
    • 2017-08-03
    • 2014-05-02
    • 2011-09-11
    相关资源
    最近更新 更多