簡體   English   中英

使用同步的生產者-消費者

[英]producer-consumer using synchronization

我寫了代碼來實現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;
     }
} 

您嘗試做的是使用忙等待實現同步。 在偽代碼中,您基本上要做的是:

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

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

您的代碼將正常工作,直到生產者和消費者同時嘗試執行Produce()和消耗()。 換句話說,這可能不是很常見,但是絕對有可能並且一定會發生!

在Java中,ConcurrentLinkedQueue為共享緩沖區實現了免等待算法。 如果您四處看看,我相信這是其他實現。

沒有the Producer-Consumer problem 生產者-消費者是一種設計模式,可能有效地解決問題,而不是問題本身。

我敢肯定,有很多不需要同步的生產者-消費者實現。 這完全取決於您要完成的工作以及生成/消費的數據類型。

另外,如果您想說實現工作沒有同步,就必須解決一個問題。 在做什么工作? 我不知道你在做什么

可以使用無鎖隊列來完成此操作,但不是這樣,我建議您閱讀實踐中的Java並發。 如果您的代碼可以同時被多個線程訪問,那么您將遇到很多錯誤,您將遇到發布和同步問題! 但是就像Farlmarri所說的,這取決於此代碼的用法。

您實際上不是在解決生產者/消費者問題,而只是在解決它:)您的代碼之所以有效,是因為時間緊迫,並且因為兩個線程之一無法放入/獲取它要求的資源基本上會休眠一段時間然后再試一次。 盡管這種擔心(當您不必立即處理事件時)會浪費CPU時間。

這就是為什么強烈建議使用信號量來解決此類問題的原因,您可以在此處閱讀

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

再見

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM