[英]ReentrantLock not giving expected result
I have created a producer consumer program using threads (wait and notify) feature. 我已经使用线程(等待和通知)功能创建了一个生产者使用者程序。 The code is - 该代码是-
/**
* Message.java ( Common object )
*/
package threads;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author chouhan_r
*
*/
public class Message {
private String message;
ReentrantLock lock = new ReentrantLock();
ReentrantLock takelock = new ReentrantLock();
private boolean empty =true;
public void put(String message){
lock.lock();
while(!empty){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
empty = false;
this.message = message;
notifyAll();
lock.unlock();
}
public String take(){
takelock.lock();
while(empty){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
empty = true;
notifyAll();
takelock.unlock();
return message;
}
}
/**
* Producer.java
*/
package threads;
import java.util.Random;
public class Producer implements Runnable{
private Message message;
public Producer(Message message) {
this.message = message;
}
@Override
public void run() {
String[] impInfo = {"Hello", "I am here", "why are you doing this ??", "No problem" };
Random random = new Random();
for(String str : impInfo){
message.put(str);
try {
Thread.sleep(random.nextInt(3000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
message.put("Finished");
}
}
/**
* Consumer.java
*/
package threads;
public class Consumer implements Runnable{
private Message message;
public Consumer(Message message) {
this.message = message;
}
@Override
public void run() {
System.out.println(message);
String msg = message.take();
while(!"Finished".equalsIgnoreCase(msg)){
System.out.println(msg);
msg = message.take();
}
}
}
===================== =====================
/**
* Main Program
*/
package threads;
public class ProConsTest {
public static void main(String[] args) {
Message message = new Message();
new Thread(new Consumer(message)).start();
new Thread(new Producer(message)).start();
}
}
I am trying to execute this code using ReentrantLock but it is giving me followin error - 我正在尝试使用ReentrantLock执行此代码,但它给了我followin错误-
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at threads.Message.take(Message.java:39)
at threads.Consumer.run(Consumer.java:11)
at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at threads.Message.put(Message.java:31)
at threads.Producer.run(Producer.java:16)
at java.lang.Thread.run(Unknown Source)
Am I doing something wrong here ?? 我在这里做错什么了吗? when I mark methods in Message.java as synchronized it works perfect. 当我在Message.java中将方法标记为同步时,它可以正常工作。 Can we run this code only with the Reentrant lock ?? 我们只能使用可重入锁运行此代码吗?
Object.wait
and Object.notify
are connected to the intrinsic locking feature, which is used with synchronized
blocks and methods. Object.wait
和Object.notify
连接到内部锁定功能,该功能与synchronized
块和方法一起使用。
If you want to use Lock
s, you can't use these two methods. 如果要使用Lock
,则不能使用这两种方法。 Instead you have to create a Condition
and call await()
on it, which should be paired with another thread calling signal()
on the same Condition
instance. 相反,您必须创建一个Condition
并在其上调用await()
,该条件应与在同一Condition
实例上另一个调用signal()
线程配对。 Note that unlike Object.wait
and Object.notify
, you can have more than one Condition
per Lock
and threads waiting for a particular condition will be woken up by threads calling signal
on the same Condition
instance. 请注意,与Object.wait
和Object.notify
不同,每个Lock
可以具有多个Condition
,并且在特定Condition
实例上调用signal
的线程将唤醒等待特定条件的线程。
However, as with the intrinsic locking feature, you must own the associated lock before calling a method on a Condition
. 但是,与内部锁定功能一样,您必须拥有关联的锁定,然后才能在Condition
上调用方法。 In case of a ReadWriteLock
, you must own the write lock. 如果是ReadWriteLock
,则您必须拥有写锁。
Unfortunately, Condition
s inherit the methods wait
and notify
from Object
, so it's important to never mix them up, which requires special care due to the hard to distinguish names, wait
and await
. 不幸的是, Condition
继承了Object
wait
和notify
方法,因此永远不要混淆它们,这一点很重要,由于很难区分名称wait
和await
,因此需要特别注意。
The documentation of Condition
contains a complete example. Condition
的文档包含一个完整的示例。 I just pick up one code fragment illustrating the usage in the put
method: 我只是拿起一个代码片段来说明put
方法的用法:
final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition();
… ...
lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.