[英]Producer Consumer in java multithreaded
我正在嘗試在Java中實現生產者使用者問題。 我正在使用循環緩沖區(循環數組),以使生產者將項目插入緩沖區。 以下是我的代碼:
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);
}
}
}
生產者正在將數據項成功插入緩沖區。 但是它們並沒有被消費者所消費。
執行程序時,我得到以下輸出。
Successfully inserted 11_1
Successfully inserted 11_2
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
Buffer full
我的問題是如何使消費者從緩沖區消費物品?
主要問題是Producer
中的synchronized
塊太寬。 永遠不會讓Consumer
獲得鎖
首先,縮小范圍,例如...
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();
}
}
}
您也可以考慮同步ing insert
和delete
方法本身。 我個人很想使用內部鎖,但是例如,您可以簡單地synchronize
方法本身。
public synchronized boolean insert(String dataitem) {...}
public synchronized String delete() {...}
就目前而言,您的Consumer
將永遠只能從緩沖區中讀取一個值,但是我會讓您找出一個值;)
附帶說明一下,我可以將wait和notify功能直接放在Buffer
,以便每當您嘗試delete
一個值時,它將在delete
方法中等待Buffer
不為空,並允許insert
方法進行操作通知本身...但是就是我;)
同樣,我可以考慮阻塞insert
方法,直到有更多空間,但這取決於您要如何實現它:P
更新
從根本上講,這將開始為您提供所需的結果...
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.