0

我编写了代码来实现生产者-消费者问题,它似乎工作正常,不需要同步。有可能吗?

我如何测试代码并检查它是否真的工作正常?我怎么知道是否会发生死锁?现在,我没有打破循环(即生产者不断插入,消费者不断地在无限循环中消费)。我使用大小为 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

4 回答 4

1

您尝试做的是使用忙等待实现同步。在伪代码中,您基本上在做的是:

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

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

您的代码将正常工作,直到生产者和消费者同时尝试执行生产()和消费()。换句话说,这其中的任何一个都可能不会经常发生,但绝对有可能并且肯定会发生!

在 Java 中,ConcurrentLinkedQueue 实现了共享缓冲区的无等待算法。如果您环顾四周,我敢肯定这是其他实现。

于 2010-12-14T19:04:55.477 回答
0

您实际上并没有解决生产者/消费者问题,而只是绕过它:)您的代码之所以有效,是因为时间安排,并且因为如果两个线程之一未能放置/检索它所要求的资源,它基本上会休眠一段时间并再次尝试。虽然这个工作(当您不必立即处理事件时)它会浪费 CPU 时间。

这就是为什么强烈建议使用信号量来解决此类问题的原因,您可以在此处阅读

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

再见

于 2010-12-14T19:09:10.277 回答
0

没有这样的事情the Producer-Consumer problem。生产者-消费者是一种设计模式,它可能是也可能不是问题解决方案的有效实现,而不是问题本身。

我确信有很多不需要同步的生产者-消费者实现。这完全取决于您要完成的工作以及您正在生产/使用的数据类型。

此外,如果你想说你的实现工作没有同步,你必须有一个问题要解决。从事什么工作?我不知道你在做什么。

于 2010-12-14T19:00:10.837 回答
0

可以使用无锁队列来完成,但不是这样,我建议您阅读 Java 并发实践。如果您的代码同时被多个线程访问,您将有很多错误,您有发布和同步问题!但就像 Farlmarri 所说的,这取决于这段代码的使用情况。

于 2010-12-14T19:02:28.343 回答