生产者使用者代码问题(似乎Notify方法不会释放循环内的锁)

时间:2018-07-13 17:17:24

标签: java multithreading

我正在尝试使用等待和通知方法来实现生产者使用者。生产者线程将一些值放入数组列表的公共容器中。现在,从头开始,如果消费者线程在列表上获得了锁定,它将检查列表的大小,如果大小为0,则它​​将进入等待状态。现在,生产者线程将第一个值放入循环中,并调用Notify方法,因此现在,消费者线程应获取通知并使用该值。再次,生产者线程应该恢复并开始for循环的下一次迭代,但是这没有发生。生产者内部的for循环将首先执行,然后运行消费者代码。

请指导我在网上搜索了很多但找不到更复杂的实现的内容。

Producer.java

package com.multithreading;

import java.util.List;

public class Producer implements Runnable {

public List<Integer> commonObject;

Producer(List<Integer> commonObject) {
    this.commonObject = commonObject;
}

@Override
public void run() {
    synchronized (commonObject) {
        System.out.println("First Thread got the lock");
        for (int i = 0; i < 500; i++) {
            System.out.println("First Thread producing value");
            commonObject.add(i);
            System.out.println("First Thread notified");
            commonObject.notifyAll();
        }
    }

}

}

Consumer.java

package com.multithreading;

import java.util.List;

public class Consumer implements Runnable {

public List<Integer> commonObject;

Consumer(List<Integer> commonObject) {
    this.commonObject = commonObject;
}

@Override
public void run() {
    synchronized (commonObject) {
        System.out.println("Second Thread got the lock");
        if (commonObject.size() == 0) {
            try {
                System.out.println("Second Thread going into Waiting state");
                commonObject.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Second Thread Consuming Value");
            for (int i : commonObject) {
                System.out.println(i);
            }
        }
    }
}

}

ProducerConsumer.java

package com.multithreading;

import java.util.ArrayList;
import java.util.List;


public class ProducerConsumer {
public static void main(String [] arg){

    List<Integer> sharedObject=new ArrayList<Integer>();
    Producer producer=new Producer(sharedObject);
    Consumer consumer=new Consumer(sharedObject);
    Thread t1= new Thread(producer);
    Thread t2= new Thread(consumer);
    t1.start();
    t2.start();
}

}

1 个答案:

答案 0 :(得分:0)

我不确定这是否会有帮助,因为我不知道具体的问题是什么,但是可能是第二个线程不能使用这些值,因为您放置了“ consume”部分else分支中的代码中,处于等待状态的线程将永远不会运行,因为它们处于if分支中?您应该将代码的“消费”部分放在else之外,这样,当它们退出等待状态后,他们就可以“消费”这些值。