Can you help me understand why the name of the thread when executing the methods "put()", and "get()", is still "main thread", and not "Producer1", and "Consumer1" respectively.
Goal: Solution in order to have the name of the threads respectively as: "Producer1", and "Consumer1" or explanation as to why this is happening.
More descriptive goal:
Producer1, Put 0
Consumer1, List is empty!
Producer1, Put 1
Consumer1, Got: [0,1]
Consumer1, Consumed: "1"
And so on…
Errors: No errors, just not desired outcome:
main thread, Put 0
main thread, List is empty!
main thread, Put 1
main thread, Got: [0,1]
main thread, Consumed: "1"
Attempts: I have also tried the ".join" method that is commented on the Main class, but the end-result is the same.
Main:
public class Main {
public static void main(String[] args) {
Q queue = new Q();
Producer producer1 = new Producer(queue, "Producer1");
//Producer producer2 = new Producer(queue, "Producer2");
Consumer consumer1 = new Consumer(queue, "Consumer1");
producer1.thread.start();
//producer2.thread.start();
consumer1.thread.start();
/*
try{
System.out.println("Waiting for threads to finish.");
producer1.thread.join();
//producer2.thread.join();
consumer1.thread.join();
} catch (InterruptedException e){
System.out.println("Thread interrupted");
System.out.println();
System.out.println(e);
}
*/
}
}
Q:
public class Q {
//int n;
boolean ready = false;
List<Integer> products;
Thread t = Thread.currentThread();
Q(){
products = new ArrayList<>(5);
}
// ------------------------
synchronized void put(int n){
while (ready){
try {
wait();
} catch (InterruptedException e){
System.out.println(t.getName() + " was interrupted!");
System.out.println();
System.out.println(e);
}
}
if(products.size() < 5){
this.products.add(n);
System.out.println(t.getName() + " thread, Put: " + n);
ready = true;
notify();
} else {
System.out.println(t.getName() + " thread, List is full!");
ready = true;
notify();
}
//this.n = n;
}
// ------------------------
synchronized List<Integer> get(){
while (!ready){
try {
wait();
} catch (InterruptedException e){
System.out.println(t.getName() + " thread was interrupted!");
System.out.println();
System.out.println(e);
}
}
if(products.size() > 1){
System.out.println(t.getName() + " thread, Got: " + products);
System.out.println(t.getName() + " thread, Consumed: \"" + (products.get(products.size() - 1)) + "\"");
removeLastElement();
ready = false;
notify();
} else {
System.out.println(t.getName() + " thread, List is empty!");
ready = false;
notify();
}
//System.out.println("Got: " + n);
//ready = false;
//notify();
return products;
}
void removeLastElement(){
int index = (this.products.size() - 1);
this.products.remove(index);
}
}
Producer:
public class Producer implements Runnable{
Q queue;
Thread thread;
Producer(Q queue, String threadName){
thread = new Thread(this, threadName);
System.out.println("Test: " + thread.getName());
this.queue = queue;
}
@Override
public void run() {
int i = 0;
for(int j = 0; j < 20; j++){
queue.put(i++);
}
}
}
Consumer:
public class Consumer implements Runnable{
Q queue;
Thread thread;
Consumer(Q queue, String threadName){
thread = new Thread(this, threadName);
System.out.println("Test: " + thread.getName());
this.queue = queue;
}
@Override
public void run() {
for(int j = 0; j < 20; j++){
queue.get();
System.out.println();
}
}
}
Can you assist?
Thank you.
>Solution :
Q‘s field Thread t is being assigned Thread.currentThread() when an instance of Q is created, and a Q is being created on your main thread. So t references the main thread from the very beginning.
Instead, remove Thread t and replace all instances of t.getName() with Thread.currentThread().getName(). This will directly retrieve the name of the thread that is actually making calls to methods of Q at runtime.
(Or, you can just declare Thread t within each method instead. It will be assigned the "current thread" which in that case would be the one calling the method.)