[英]Producer Consumer in java multithreaded
I'm trying to implement a Producer Consumer problem in java. 我正在尝试在Java中实现生产者使用者问题。 I'm using a circular buffer (circular array) to for the Producer to insert items into the buffer. 我正在使用循环缓冲区(循环数组),以使生产者将项目插入缓冲区。 Following is my code: 以下是我的代码:
import java.util.*;
import java.io.*;
public class Buffer
{
String a[];
int front, rear;
public Buffer(int size)
{
a = new String[size];
front = rear = -1;
}
public boolean insert(String dataitem)
{
int p;
p = (rear+1) % a.length;
if(p==front)
{
System.out.println("Buffer full");
return false;
}
else
{ rear = p;
a[rear] = dataitem;
if(front == -1)
front = 0;
return true;
}
}
public boolean empty()
{
if(front == -1)
return true;
else
return false;
}
public String delete()
{
String result = a[front];
if(front == rear)
front = rear = -1;
else
front = (front +1)%a.length;
return result;
}
public void display()
{
if(front == -1)
System.out.println("Buffer empty");
else
{
System.out.println("Buffer elements are:");
int i= front;
while(i!= rear)
{
System.out.println(a[i]);
i = (i+1)%a.length;
}
System.out.println(a[i]);
}
}
public static void main(String[] args)
{
int size = Integer.parseInt(args[0]);
Buffer b = new Buffer(size);
int ch;
String dataitem, msg;
Thread prod = new Thread(new Producer(b, size));
Thread cons = new Thread(new Consumer(b, size));
prod.start();
cons.start();
}
}
class Producer extends Thread
{
Buffer b;
int size;
public Producer(Buffer b, int size)
{
this.b = b;
this.size = size;
}
public void run()
{
while(true)
{
synchronized(b)
{
for(int i = 1; i <= size; i++)
{
try
{ String dataitem = Thread.currentThread().getId()+"_"+i;
boolean bool = b.insert(dataitem);
//b.notifyAll();
if(bool)
System.out.println("Successfully inserted "+dataitem);
b.notifyAll();
Thread.sleep(2000);
}
catch(Exception e)
{ e.printStackTrace();
}
}
}
}
}
}
class Consumer extends Thread
{
Buffer b;
int size;
public Consumer(Buffer b, int size)
{
this.b = b;
this.size = size;
}
public void run()
{
while(b.empty())
{
synchronized(b)
{
try
{
System.out.println("Buffer empty");
b.wait();
}
catch(Exception e)
{ e.printStackTrace();
}
}
}
synchronized(b)
{
b.notifyAll();
String dataitem = b.delete();
System.out.println("Removed "+dataitem);
}
}
}
The producer is inserting dataitems into the buffer successfully. 生产者正在将数据项成功插入缓冲区。 But they aren't being consumed by the consumer. 但是它们并没有被消费者所消费。
I get the following output when I execute the program. 执行程序时,我得到以下输出。
Successfully inserted 11_1
Successfully inserted 11_2
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
My question is how do I get the consumer to consume items from the buffer? 我的问题是如何使消费者从缓冲区消费物品?
The major problem is that the synchronized
block in your Producer
is too wide. 主要问题是Producer
中的synchronized
块太宽。 It is never letting the Consumer
acquire the lock 永远不会让Consumer
获得锁
Start by narrowing the scope, for example... 首先,缩小范围,例如...
while (true) {
for (int i = 1; i <= size; i++) {
try {
String dataitem = Thread.currentThread().getId() + "_" + i;
boolean bool = b.insert(dataitem);
//b.notifyAll();
if (bool) {
System.out.println("Successfully inserted " + dataitem);
}
synchronized (b) {
b.notifyAll();
}
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
You may also consider synchronizing the ing insert
and delete
methods themselves. 您也可以考虑同步ing insert
和delete
方法本身。 I personally would be tempted to use a internal lock, but you could simply synchronize
the methods themselves, for example... 我个人很想使用内部锁,但是例如,您可以简单地synchronize
方法本身。
public synchronized boolean insert(String dataitem) {...}
public synchronized String delete() {...}
As it stands, your Consumer
will only ever read a single value from the buffer, but I'll let you figure that one out ;) 就目前而言,您的Consumer
将永远只能从缓冲区中读取一个值,但是我会让您找出一个值;)
As a side note, I might put the wait and notify functionality directly within the Buffer
, so that whenever you try and delete
a value, it will wait, within the delete
method for the Buffer
to be not empty and allow the insert
method to make the notifications itself...but that's me ;) 附带说明一下,我可以将wait和notify功能直接放在Buffer
,以便每当您尝试delete
一个值时,它将在delete
方法中等待Buffer
不为空,并允许insert
方法进行操作通知本身...但是就是我;)
Equally, I might consider blocking the insert
method until there is more room, but that will come down to how you want to implement it :P 同样,我可以考虑阻塞insert
方法,直到有更多空间,但这取决于您要如何实现它:P
Updated 更新
Very basically, this will start giving the results you are looking for... 从根本上讲,这将开始为您提供所需的结果...
public class ProducerConsumer {
public static void main(String[] args) {
new ProducerConsumer();
}
public ProducerConsumer() {
int size = 5;
Buffer b = new Buffer(size);
Thread prod = new Thread(new Producer(b, size));
Thread cons = new Thread(new Consumer(b, size));
prod.start();
cons.start();
}
public class Buffer {
String a[];
int front, rear;
public Buffer(int size) {
a = new String[size];
front = rear = -1;
}
public synchronized boolean insert(String dataitem) {
int p;
p = (rear + 1) % a.length;
if (p == front) {
System.out.println("Buffer full");
return false;
} else {
rear = p;
a[rear] = dataitem;
if (front == -1) {
front = 0;
}
return true;
}
}
public boolean empty() {
return front == -1;
}
public synchronized String delete() {
String result = a[front];
if (front == rear) {
front = rear = -1;
} else {
front = (front + 1) % a.length;
}
return result;
}
public void display() {
if (front == -1) {
System.out.println("Buffer empty");
} else {
System.out.println("Buffer elements are:");
int i = front;
while (i != rear) {
System.out.println(a[i]);
i = (i + 1) % a.length;
}
System.out.println(a[i]);
}
}
}
class Producer extends Thread {
Buffer b;
int size;
public Producer(Buffer b, int size) {
this.b = b;
this.size = size;
}
public void run() {
int i = 0;
while (true) {
try {
String dataitem = Thread.currentThread().getId() + "_" + ++i;
boolean bool = b.insert(dataitem);
if (bool) {
System.out.println("Successfully inserted " + dataitem);
}
synchronized (b) {
b.notifyAll();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Consumer extends Thread {
Buffer b;
int size;
public Consumer(Buffer b, int size) {
this.b = b;
this.size = size;
}
public void run() {
while (true) {
while (b.empty()) {
synchronized (b) {
try {
System.out.println("Buffer empty");
b.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
String dataitem = null;
synchronized (b) {
dataitem = b.delete();
}
System.out.println("Removed " + dataitem);
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.