生产者 - 消费者示例不起作用

时间:2018-04-05 22:10:44

标签: java multithreading producer-consumer

有人可以帮我修复这个程序。我创建了一个使用Scanner类请求输入的生成器类,接下来我创建了一个使用Consumer的类,我使用了那些长度和宽度的输入来计算Area。最后,我创建了一个带有main方法的类来启动生产者和消费者线程。

生产者: -

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

}

CONSUMER: -

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;
  }
}

主要课程: -

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

    }

}

我期待控制台向我询问输入(它确实如此),接下来我期待它通知线程等待锁定在消费者类上发布(我认为不会发生)然后我期待它计算面积并让消费者回到等待状态(这也不会发生,并要求更多的投入。

1 个答案:

答案 0 :(得分:0)

synchronize(...)标记了一个关键部分,其中只允许一个线程执行代码块。虽然您通知消费者线程唤醒,但您的生产者线程几乎立即回收其类的内部锁并请求下一个输入,因为它不必等待任何其他输入或必须执行临界区之外的代码需要几个CPU周期。切换线程的上下文可能需要一段时间,因为它并不便宜。这个开销足以使生产者线程可以在循环的下一次迭代中再次进入临界区,因此回收专用权来执行其代码,该代码只是等待用户输入。另一方的消费者线程在被激活后注意到另一个线程(生产者线程)获得了关键部分的内在锁定并再次被暂停。

如果您将生产者中的同步块仅限于通知并从关键部分排除输入处理,则样本应按预期工作,因为生产者需要更多的CPU周期才能再次到达同步块,因此允许消费者线程实际获取内部锁并执行其任务。