首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java锁条件似乎不能正常工作

Java锁条件似乎不能正常工作
EN

Stack Overflow用户
提问于 2020-04-02 04:16:35
回答 1查看 56关注 0票数 1

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

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

不幸的是,它不是我想要的工作方式,似乎消费者/生产者,当他们在Condition.await中时,不让其他线程工作。他们不应该让他们这样做吗?

以下是我的代码

代码语言:javascript
复制
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) {}
        }
    }
}

提前感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-02 05:47:33

不要将内部锁(即synchronized)与reentrantLocks混合在一起。这段代码试图先获取内部锁,然后再获取重入锁。

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

(具体地说,代码在条件对象上调用await,这会导致线程释放可重入的锁,但线程会一直持有固有的锁,从而阻止其他线程进入同步方法。)

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60979566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档