Domanda

Ho scritto codice per implementare il problema produttore-consumatore e sembra funzionare bene senza la necessità di synchronize.Is possibile?

Come faccio a testare il codice e verificare se è in realtà di lavoro giusto o no? Come faccio a sapere se si verificherà situazione di stallo? In questo momento, io non sto rompendo dai passanti (cioè il produttore tiene l'inserimento e il consumatore mantiene consumare in un loop infinito) .Io sto usando una coda circolare di dimensioni 3 (per semplicità) come risorsa condivisa.

Ecco il mio codice:

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;
     }
} 
È stato utile?

Soluzione

Quello che abbiamo cercato di fare è implementare la sincronizzazione utilizzando busy-attesa. In pseudo codice quello che stai facendo è fondamentalmente:

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

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

È il codice funziona bene, fino al il produttore e il consumatore allo stesso tempo provare ad eseguire prodotti () e consumare (). In altre parole, o uno dei questo potrebbe non essere molto spesso, ma è sicuramente possibile e sicuramente accadrà!

In Java, ConcurrentLinkedQueue ad implementa un algoritmo priva di attesa per un buffer condiviso. Sono sicuro che sono altre implementazioni se si guarda intorno.

Altri suggerimenti

Non c'è cosa come the Producer-Consumer problem. Produttore-consumatore è un modello di progettazione che può o non può essere un efficace implementazione di una soluzione ad un problema, non è un problema in sé e per sé.

Sono sicuro che ci sono un sacco di implementazioni produttore-consumatore che non richiedono la sincronizzazione. Dipende tutto da cosa si sta cercando di realizzare e che tipo di dati si sta producendo / consumando.

Inoltre, è necessario disporre di un problema da risolvere se si vuole dire che sei opere di implementazione, senza sincronizzazione. Lavora a fare che cosa? Non ho idea di quello che stai facendo.

Si può fare con una coda libera della serratura, ma non in questo modo, vi consiglio di leggere Java Concurrency in Practice. Se il codice è l'accesso da più thread allo stesso tempo avrete molte erros su questo, si hanno problemi di pubblicazione e syncronizations !! Ma come Farlmarri ha detto che dipende l'utilizzo di questo codice.

non sono in realtà la soluzione del produttore / consumatore problema, ma solo a piedi intorno ad esso :) Il tuo codice funziona a causa della tempistica e per il fatto se uno dei due fili fallisce mettendo / recuperare la risorsa che richiede fondamentalmente dorme per un nuovo mentre e tentativi. Anche se questo worsk (quando non si deve gestire immediatamente un evento) spreca tempo di CPU.

Ecco perché i semafori sono fortemente suggeriti per affrontare questo tipo di problema, come si può leggere qui

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

bye

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top