我刚刚创建了一个生产者和一个消费者线程。当列表为空时,消费者进入等待状态,然后生产者在列表中插入一个项目并调用notify()
来调用消费者线程但消费者没有调用。它仍处于等待状态。
我尝试的代码是:
package xs;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class TestMain {
public static void main(String[] args) {
product pro = new product();
producer produce = new producer(pro);
consumer consume = new consumer(pro);
Thread thr1 = new Thread(produce, "Producer");
Thread thr2 = new Thread(consume, "consumer");
thr1.start();
thr2.start();
}
}
class product{
List<Date> list;
public product() {
list = new ArrayList<Date>();
}
public void produce(Date i){
list.add(i);
}
public Date consume(){
return list.remove(0);
}
}
class producer implements Runnable{
product product;
@Override
public void run() {
while(true){
synchronized (this) {
while(product.list.size() == 2){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
product.produce(new Date());
System.out.println("Produced "+product.list.size());
notify();
}
}
}
public producer(product product) {
this.product = product;
}
}
class consumer implements Runnable{
product product;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (this) {
notify();
while(product.list.size() == 0){
try {
System.out.println("Going to wait..."+ product.list.size());
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("consumed"+ product.consume());
}
}
}
public consumer(product product) {
this.product = product;
}
}
输出它给出:
Going to wait...0
Produced 1
Produced 2
正如您所见,消费者在wait()
致电后没有采取行动。
答案 0 :(得分:2)
您的制作人和消费者都在同步,等待和通知他们自己的监视器。您需要为它们提供共享监视器以用于同步等。
例如:
Object monitor = new Object();
product pro = new product();
producer produce = new producer(monitor, pro);
consumer consume = new consumer(monitor, pro);
更改producer
和consumer
构造函数以接受另一个参数(类型为Object
)并将其保存在字段中,然后将synchronized(this)
更改为synchronized(monitor)
},wait()
到monitor.wait()
和notify()
到monitor.notify()
,一切都会好的。
(你可以只使用product
进行同步,但我个人更喜欢使用仅用于同步的对象,或者一个专门为此设计的以线程为中心的类。)
另外,请注意,由于您的类名称应该Product
,Producer
和Consumer
来遵循正常的Java命名约定,因此您的代码感觉非常类似于Java。 / p>
答案 1 :(得分:-2)
@deepak:你犯了一个错误,你通过了字符串名称小写
线程thr2 =新线程(消费,“消费者”);
到位你应该通过 线程thr2 =新线程(消耗,“消费者”);
其中“消费者”是消费者的类名
我得到了这个输出:
Produced 1
Produced 2
consumedTue Oct 07 13:29:44 IST 2014
consumedTue Oct 07 13:29:44 IST 2014
Going to wait...0