简体   繁体   English

使用同步的生产者-消费者

[英]producer-consumer using synchronization

I wrote code to implement the Producer-Consumer problem and it seems to be working fine without the need to synchronize.Is it possible? 我写了代码来实现Producer-Consumer问题,似乎不需要同步就可以正常工作,这可能吗?

How do I test the code and check if it is actually working right or not? 如何测试代码并检查其是否正常工作? How do I know if deadlock will occur? 我怎么知道是否会发生死锁? Right now,I am not breaking out of the loops(ie the Producer keeps inserting and the consumer keeps consuming in an infinite loop).I am using a circular queue of size 3(for sake of simplicity) as the shared resource. 现在,我并没有脱离循环(即生产者不断插入而消费者不断陷入无限循环)。我使用大小为3(为简单起见)的循环队列作为共享资源。

Here is my code: 这是我的代码:

import java.util.*;

public class PCImpl implements Runnable 
{
Thread t;
QforPC qObj;

 public static void main(String[] args)
 {
     QforPC qObject=new QforPC();

     //These create 2 different objects! Each object has it's own thread of execution.
     //Synchronization is needed when 2 threads use the same object
    new PCImpl("Producer",qObject);
    new PCImpl("Consumer",qObject);
 }

 PCImpl(String name,QforPC qObj)
 {
     this.qObj=qObj;
     t=new Thread(this,name);
     t.start();
 }

 public void run()
 {
         if(Thread.currentThread().getName().equals("Producer"))
         {
             while(true)
             {
                  Random rgen=new Random();
                  int n=rgen.nextInt(100);
                  if(n!=0)
                              qObj.Producer(n);
                         try
                    {
                       Thread.sleep(200);
                     }
                      catch(InterruptedException e)
                    {

                    }
               }

            }


         if(Thread.currentThread().getName().equals("Consumer"))
         {
             while(true)
                  {
                 try
               {
                 Thread.sleep(1500);
               }
                catch(InterruptedException e)
               {
                  }
              qObj.Consumer();

              }
         }

  }
}



public class QforPC 
{
int[] q={0,0,0};
int r=0,f=0;
  public void Producer(int item)
     {

         if(r!=q.length && canProducer())
         {
             q[r]=item;
             System.out.println("The item inserted into the queue is:"+ item);
             r++;
         }
         if(r==q.length && f>0)
             r=0;
         else if(r==q.length && f==q.length)
         {
             r=0;
             f=0;
         }
     }

     public void Consumer()
     {
         int item;
         System.out.println("The value of isQueue empty is:"+ isEmpty());

         if(f!=q.length && isEmpty()==false)
         {
             System.out.println("Entered the consumer method");
             item=q[f];
             System.out.println("The item fetched from the queue is:"+item);
             q[f]=0;
             f++;
         }
         if(f==q.length && r<f)
             f=0;

     }

     public boolean isEmpty()
     {
         for(int k=0;k<q.length;k++)
         {
             if(q[k]==0 && k==q.length-1)
                 return true;

         }
         return false;
     }

     public boolean canProducer()
     {
         for(int k=0;k<q.length;k++)
         {
                 if(q[k]==0)
                 return true;

         }
         return false;
     }
} 

What you have tried to do is implement synchronization using busy-waiting. 您尝试做的是使用忙等待实现同步。 In pseudo code what you are basically doing is: 在伪代码中,您基本上要做的是:

Producer()
{
   if (buffer.hasemptyspaces())
   {
      produce(buffer);
   }
   else
   {
      sleep(n);
   }
}

Consumer()
{
   if (buffer.hasfullspaces())
   {
      consume(buffer);
   }
   else
   {
      sleep(n);
   }
}

You code will work fine, till the the Producer and Consumer simultaneously try to execute produce() and consume(). 您的代码将正常工作,直到生产者和消费者同时尝试执行Produce()和消耗()。 In other words, either one of the This might not be very often, but is definitely possible and will definitely happen! 换句话说,这可能不是很常见,但是绝对有可能并且一定会发生!

In Java, ConcurrentLinkedQueue to implements a wait-free algorithm for a shared buffer. 在Java中,ConcurrentLinkedQueue为共享缓冲区实现了免等待算法。 I'm sure that are other implementations if you look around. 如果您四处看看,我相信这是其他实现。

There's no such thing as the Producer-Consumer problem . 没有the Producer-Consumer problem Producer-Consumer is a design pattern that may or may not be an effective implementation of a solution to a problem, not a problem in and of itself. 生产者-消费者是一种设计模式,可能有效地解决问题,而不是问题本身。

I'm SURE there are plenty of producer-consumer implementations that don't require synching. 我敢肯定,有很多不需要同步的生产者-消费者实现。 It entirely depends on what you're trying to accomplish and what kind of data you're producing/consuming. 这完全取决于您要完成的工作以及生成/消费的数据类型。

Also, you have to have a problem to solve if you want to say you're implementation works without synchronizing. 另外,如果您想说实现工作没有同步,就必须解决一个问题。 Works at doing what? 在做什么工作? I have no idea what you're doing. 我不知道你在做什么

It can be done with a lock free queue, but not like this, i recommend that you read Java Concurrency in Practice. 可以使用无锁队列来完成此操作,但不是这样,我建议您阅读实践中的Java并发。 If your code is access by multiple threads at the same time you will have many erros on that, you have publication and syncronizations problems!! 如果您的代码可以同时被多个线程访问,那么您将遇到很多错误,您将遇到发布和同步问题! But like Farlmarri said it depends on the usage of this code. 但是就像Farlmarri所说的,这取决于此代码的用法。

you are actually not solving the producer/consumer problem but just walking around it :) Your code works because of the timing and because of the fact if one of the two threads fails putting/retrieving the resource it asks for it basically sleeps for a while and tries again. 您实际上不是在解决生产者/消费者问题,而只是在解决它:)您的代码之所以有效,是因为时间紧迫,并且因为两个线程之一无法放入/获取它要求的资源基本上会休眠一段时间然后再试一次。 Although this worsk (when you do not have to immediatly handle an event) it wastes CPU time. 尽管这种担心(当您不必立即处理事件时)会浪费CPU时间。

That is why semaphores are strongly suggested to address this kind of issue as you can read here 这就是为什么强烈建议使用信号量来解决此类问题的原因,您可以在此处阅读

http://en.wikipedia.org/wiki/Producer-consumer_problem http://en.wikipedia.org/wiki/Producer-consumer_problem

bye 再见

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM