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

标签 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();
        }
    }

}

}


消费者.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();
}

}

最佳答案

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

关于java - 生产者使用者代码问题(似乎Notify方法不会释放循环内的锁),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51330009/

相关文章:

multithreading - 可以从另一个 QThread 安全地发出 Qt 信号吗

c# - Backgroundworker 和 TPL 的 Task 有相同的 ManagedThreadID?

java - 此处不允许列 oracle 与 getText

java - 如何使用控制台运行 jnlp 应用程序?

java - 使用 Firebase 数据填充 Android 微调器

android - 从 C (NDK) 调用 Thread.yield() 或等效函数

java - 后面和前面的撇号

java - 如何避免 swagger codegen 接口(interface)中的默认方法实现?

c++ - 线程间通信。如何向另一个线程发送信号

java - Java流在完成上一个 map 之前开始下一个 map