Производитель-потребитель с использованием синхронизации

StackOverflow https://stackoverflow.com/questions/4443025

Вопрос

Я написал код, чтобы реализовать проблему-производителя-потребителя, и, похоже, он работает нормально без необходимости синхронизации. Это возможно?

Как проверить код и проверить, действительно ли он работает правильно или нет? Как я узнаю, произойдет ли тупик? Прямо сейчас я не вырываю петли (то есть производитель продолжает вставлять, и потребитель продолжает потреблять в бесконечной цикле). Я использую круговую очередь размера 3 (ради простоты) в качестве общего ресурса.

Вот мой код:

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;
     }
} 
Это было полезно?

Решение

То, что вы пытались сделать, это реализовать синхронизацию, используя ожидание занятости. В псевдо -коде то, что вы в основном делаете:

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

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

Вы код будет работать нормально, пока производитель и потребитель одновременно попытаются выполнить продукт () и потреблять (). Другими словами, любой из этого может быть не очень часто, но определенно возможно и определенно произойдет!

В Java, CONDRENTLINKEDQUEUE, реализует алгоритм без ожидания для общего буфера. Я уверен, что это другие реализации, если вы осмотрите.

Другие советы

Нет такой вещи, как the Producer-Consumer problem. Анкет Производитель Consumer-это дизайн-шаблон, который может быть или не быть эффективной реализацией решения проблемы, а не само по себе проблема.

Я уверен, что есть много реализаций производителя-потребителя, которые не требуют синхронизации. Это полностью зависит от того, чего вы пытаетесь выполнить и какие данные вы производите/потребляете.

Кроме того, у вас должна быть проблема для решения, если вы хотите сказать, что вы работаете внедрение без синхронизации. Работает на что делать? Я понятия не имею, что вы делаете.

Это можно сделать с помощью беззаконной очереди, но не так, я рекомендую вам прочитать параллелизм Java на практике. Если ваш код доступен по нескольким потокам одновременно, у вас будет много ошибок, у вас есть проблемы с публикацией и синклонизацией !! Но, как сказал Фарлмарри, это зависит от использования этого кода.

Вы на самом деле не решаете проблему производителя/потребителя, а просто ходите по ней :) Ваш код работает из -за времени и из -за факта, если одна из двух потоков не удается вмещать/извлекать ресурс, который он просит в основном спит какое -то время и снова пытается. Хотя это Ворск (когда вам не нужно немедленно обрабатывать событие), он тратит время на ЦП.

Вот почему семафоры настоятельно рекомендуются решить эту проблему, как вы можете прочитать здесь

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

до свидания

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top