Java 锁定条件似乎无法正常工作
Java lock conditions seem to not be working right
我有一个问题,有 BoundedBuffer
和 Consumers
和 Producers
,生产者填充缓冲区,消费者从缓冲区中删除。
我正在为消费者和生产者使用线程,并且我试图使用锁定条件来确保缓冲区对生产者来说不是满的,对消费者来说不是空的。
不幸的是,它没有按照我想要的方式工作,似乎 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
关键字。
我有一个问题,有 BoundedBuffer
和 Consumers
和 Producers
,生产者填充缓冲区,消费者从缓冲区中删除。
我正在为消费者和生产者使用线程,并且我试图使用锁定条件来确保缓冲区对生产者来说不是满的,对消费者来说不是空的。
不幸的是,它没有按照我想要的方式工作,似乎 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
关键字。