我编写了代码来实现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;
}
}
答案 0 :(得分:1)
您尝试做的是使用忙等待实现同步。在伪代码中,你基本上做的是:
Producer()
{
if (buffer.hasemptyspaces())
{
produce(buffer);
}
else
{
sleep(n);
}
}
Consumer()
{
if (buffer.hasfullspaces())
{
consume(buffer);
}
else
{
sleep(n);
}
}
您的代码可以正常工作,直到Producer和Consumer同时尝试执行produce()和consume()。换句话说,其中任何一个可能不是很常见,但肯定是可能的,肯定会发生!
在Java中,ConcurrentLinkedQueue为共享缓冲区实现无等待算法。如果你环顾四周,我确信这是其他实现。
答案 1 :(得分:0)
没有the Producer-Consumer problem
之类的东西。生产者 - 消费者是一种设计模式,可能是也可能不是解决问题的有效方法,而不是问题本身。
我确实有很多生产者 - 消费者实现不需要同步。这完全取决于您要完成的工作以及您正在制作/消费的数据类型。
此外,如果您想在没有同步的情况下说您的实施工作,则必须解决问题。在做什么工作?我不知道你在做什么。
答案 2 :(得分:0)
可以使用无锁队列来完成,但不是这样,我建议你阅读Java Concurrency in Practice。如果您的代码同时被多个线程访问,那么您将拥有许多错误,那么您就会遇到发布和同步问题!但是像Farlmarri说的那样取决于这段代码的用法。
答案 3 :(得分:0)
你实际上并没有解决生产者/消费者的问题,而只是走动它:) 您的代码因为时间而工作,并且因为如果两个线程中的一个未能放置/检索它要求的资源,它基本上会休眠一段时间并再次尝试。虽然这种情况很糟糕(当你不必立即处理事件时)它会浪费CPU时间。
这就是为什么强烈建议使用信号量来解决这类问题,因为你可以在这里阅读
http://en.wikipedia.org/wiki/Producer-consumer_problem
再见