生产者消费者示例不起作用
Producer-Consumer example not working
谁能帮我修复这个程序。我创建了一个使用扫描仪 class 请求输入的生产者 class,接下来我创建了一个 class 消费者,我在其中使用长度和宽度的输入来计算面积。最后,我用 main 方法创建了一个 class 来启动生产者和消费者线程。
制作人:-
package Test1;
import java.util.*;
public class Producer extends Thread
{
public int length;
public int width;
Scanner scan=new Scanner(System.in);
public void run()
{
while(true)
{
synchronized(this)
{
length=scan.nextInt();
width=scan.nextInt();
this.notify();
}
}
}
}
消费者:-
package Test1;
public class Consumer extends Thread
{
Producer producer;
Consumer(Producer producer)
{
this.producer=producer;
}
public void run()
{
while(true)
{
synchronized(producer)
{
try
{
System.out.println("Waiting for values from the Producer");
producer.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
int area= calculateArea();
System.out.println("Area is "+area);
}
}
}
public int calculateArea()
{
return producer.length *producer.width;
}
}
主要CLASS:-
package Test1;
public class UsingPandC extends Thread {
public static void main(String[] args)
{
Producer producer=new Producer();
Consumer consumer=new Consumer(producer);
producer.start();
consumer.start();
}
}
我期待控制台向我询问输入(它确实如此),接下来我期待它通知线程等待释放消费者的锁class(我认为确实如此不会发生)然后我期待它计算面积并将消费者返回等待状态(这也不会发生并要求更多输入。
synchronize(...)
标记一个临界区,其中只允许一个线程执行代码块。尽管您通知消费者线程唤醒,但您的生产者线程几乎立即收回其 class 的内在锁并请求下一个输入,因为它不必等待任何其他内容或必须执行关键代码之外的代码需要几个 CPU 周期的部分。切换线程的上下文可能需要一些时间,因为它并不便宜。这种开销足以使生产者线程可以在循环的下一次迭代中再次进入临界区,从而收回执行其代码的独占权,该代码仅等待用户输入。另一端的消费者线程在激活后注意到另一个线程(生产者线程)获得了关键部分的内部锁并再次挂起。
如果您将生产者中的同步块限制为仅通知并排除关键部分的输入处理,您的示例应该按预期工作,因为现在生产者需要更多 CPU 周期才能达到同步再次阻塞,因此允许消费者线程实际获取内在锁并执行其任务。
谁能帮我修复这个程序。我创建了一个使用扫描仪 class 请求输入的生产者 class,接下来我创建了一个 class 消费者,我在其中使用长度和宽度的输入来计算面积。最后,我用 main 方法创建了一个 class 来启动生产者和消费者线程。
制作人:-
package Test1;
import java.util.*;
public class Producer extends Thread
{
public int length;
public int width;
Scanner scan=new Scanner(System.in);
public void run()
{
while(true)
{
synchronized(this)
{
length=scan.nextInt();
width=scan.nextInt();
this.notify();
}
}
}
}
消费者:-
package Test1;
public class Consumer extends Thread
{
Producer producer;
Consumer(Producer producer)
{
this.producer=producer;
}
public void run()
{
while(true)
{
synchronized(producer)
{
try
{
System.out.println("Waiting for values from the Producer");
producer.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
int area= calculateArea();
System.out.println("Area is "+area);
}
}
}
public int calculateArea()
{
return producer.length *producer.width;
}
}
主要CLASS:-
package Test1;
public class UsingPandC extends Thread {
public static void main(String[] args)
{
Producer producer=new Producer();
Consumer consumer=new Consumer(producer);
producer.start();
consumer.start();
}
}
我期待控制台向我询问输入(它确实如此),接下来我期待它通知线程等待释放消费者的锁class(我认为确实如此不会发生)然后我期待它计算面积并将消费者返回等待状态(这也不会发生并要求更多输入。
synchronize(...)
标记一个临界区,其中只允许一个线程执行代码块。尽管您通知消费者线程唤醒,但您的生产者线程几乎立即收回其 class 的内在锁并请求下一个输入,因为它不必等待任何其他内容或必须执行关键代码之外的代码需要几个 CPU 周期的部分。切换线程的上下文可能需要一些时间,因为它并不便宜。这种开销足以使生产者线程可以在循环的下一次迭代中再次进入临界区,从而收回执行其代码的独占权,该代码仅等待用户输入。另一端的消费者线程在激活后注意到另一个线程(生产者线程)获得了关键部分的内部锁并再次挂起。
如果您将生产者中的同步块限制为仅通知并排除关键部分的输入处理,您的示例应该按预期工作,因为现在生产者需要更多 CPU 周期才能达到同步再次阻塞,因此允许消费者线程实际获取内在锁并执行其任务。