gpt4 book ai didi

java - ReentrantLock 没有给出预期的结果

转载 作者:行者123 更新时间:2023-11-30 07:01:00 26 4
gpt4 key购买 nike

我使用线程(等待和通知)功能创建了一个生产者消费者程序。代码是——

/**
* 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();



}

}

我正在尝试使用 ReentrantLock 执行此代码,但它给我以下错误 -

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)

我是不是做错了什么??当我将 Message.java 中的方法标记为同步时,它工作得很好。我们可以只使用可重入锁运行这段代码吗??

最佳答案

Object.waitObject.notify连接到内部锁定功能,与 synchronized 一起使用 block 和方法。

如果你想使用Lock s,你不能用这两种方法。相反,你必须 create a Condition 并调用 await() 在上面,它应该与另一个调用 signal() 的线程配对同样Condition实例。请注意,与 Object.wait 不同和 Object.notify , 你可以有多个 ConditionLock等待特定条件的线程将被调用 signal 的线程唤醒在同一个 Condition实例。

但是,与内在锁定功能一样,在调用 Condition 上的方法之前,您必须拥有关联的锁。 .如果是 ReadWriteLock ,您必须拥有写锁。

不幸的是,Condition s 继承方法 waitnotify来自 Object , 所以永远不要混淆它们很重要,由于难以区分名称,这需要特别小心,waitawait .

documentation of Condition 包含一个完整的例子。我只是拿起一个代码片段来说明 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();
}

关于java - ReentrantLock 没有给出预期的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30103259/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com