I am a beginner in Java trying producer consumer problem using multi-threading in Java.
All classes are in one file with imports:
import java.util.LinkedList;
import java.util.*;
For readability I have split them here.
class fun {
LinkedList<Integer> list = new LinkedList<>();
int capacity=3;
synchronized void produce()throws InterruptedException {
int val=0;
while(true) {
while(list.size() == capacity) {
wait();
}
System.out.println("Producer Produced : "+val);
list.add(val);
val++;
notify();
}
}
synchronized void consume() throws InterruptedException {
while(true) {
while(list.size() == 0) {
wait();
}
int val;
val = list.removeFirst();
System.out.println("Consumer consumed-"+ val);
notify();
}
}
}
class a
defines one thread:
class a extends Thread {
public void run() {
try {
fun obj=new fun();
obj.produce();
} catch(InterruptedException e) {
System.out.println(e);
}
}
}
class b
defines the other thread:
class b extends Thread {
public void run() {
try {
fun obj=new fun();
obj.consume();
} catch(InterruptedException e) {
System.out.println(e);
}
}
}
class pcp
contains the main
method:
class pcp {
public static void main(String[]args) throws InterruptedException {
a t1=new a();
b t2=new b();
t1.start();
System.out.println(t1.isAlive());
t2.start();
System.out.println(t1.isAlive());
t1.join();
t2.join();
}
}
C:\javaprogs>java pcp
true
true
Producer Produced : 0
Producer Produced : 1
Producer Produced : 2
I have been checking what's wrong in my Java code but I cant find any answer.
The problem with your code/approach is that, you are using two different objects of class fun
which ideally should have been a common shared resource among multiple threads.
Inside class
b
you are instantiating new object offun
as shown below
try{
fun obj=new fun();
obj.consume();
}
As instance of class b
was never shared, below condition would always met
while(list.size() == 0) {
wait();
}
and there would no other thread notifying to this waiting thread, because your producer thread is dealing with monitor of a
; not b
. This is causing your producer thread to continue only printing aforesaid stuff.
Now, to get rid of this issue, you can follow below steps
fun
as a member of class a
& b
botha
& b
accepting fun
type and initialise it with member variablerun()
method, try invoking produce()
& consume()
on fun
member variablefun
and use it to create instances of a
& b
Complete code with some modifications to your code is shown below.
import java.util.*;
public class pcp {
public static void main(String[] args) throws InterruptedException {
fun f = new fun();
a t1=new a(f);
b t2=new b(f);
t1.start();
System.out.println(t1.isAlive());
t2.start();
System.out.println(t1.isAlive());
t1.join();
t2.join();
}
}
class fun {
LinkedList<Integer> list = new LinkedList<>();
int capacity = 3;
synchronized void produce() throws InterruptedException {
int val = 0;
while (true) {
while (list.size() == capacity) {
wait();
}
System.out.println("Producer Produced : " + val);
list.add(val);
val++;
notify();
Thread.sleep(1000);
}
}
synchronized void consume() throws InterruptedException {
while (true) {
while (list.size() == 0) {
wait();
}
int val;
val = list.removeFirst();
System.out.println("Consumer consumed-" + val);
notify();
Thread.sleep(1000);
}
}
}
class a extends Thread {
fun f;
a(fun f) {
this.f = f;
}
public void run() {
try {
f.produce();
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
class b extends Thread {
fun f;
b(fun f) {
this.f = f;
}
public void run() {
try {
f.consume();
} catch (InterruptedException e) {
System.out.println(e);
}
}
}