производитель-потребитель, использующий синхронизацию - PullRequest
0 голосов
/ 14 декабря 2010

Я написал код для реализации проблемы Producer-Consumer, и кажется, что он работает нормально без синхронизации. Возможно ли это?

Как мне проверить код и проверить, работает ли он правильно или нет? Как узнать, возникнет ли тупик? Прямо сейчас я не разрываю циклы (то есть источник продолжает вставлять, а потребитель продолжает потреблять в бесконечном цикле). Я использую круговую очередь размера 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;
     }
} 

Ответы [ 4 ]

1 голос
/ 14 декабря 2010

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

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

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

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

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

0 голосов
/ 14 декабря 2010

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

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

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

пока

0 голосов
/ 14 декабря 2010

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

0 голосов
/ 14 декабря 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...