0

I am learning how to use the wait() and notify() methods by myself and I tried to make a simple program that outputs "Jack male"and "Jane female" alternately for 50 times. I have the resource class that includes the methods that my two threads are going to use. This is what it looks like:

public class ShareResource {
    String name;
    String gender;
    boolean isEmpty = true;

    synchronized public void push(String name, String gender) {
        try {
            while (isEmpty==false) {
                this.wait();
            }
            this.name = name;
            Thread.sleep(10);
            this.gender = gender;
            isEmpty = false;
            this.notify();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    synchronized public void pop() {
        try {
            while (isEmpty) {
                this.wait();
            }
            Thread.sleep(10);
            System.out.println(this.name + " "+this.gender);
            isEmpty = true;
            this.notify();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
I also have two classes: the Producer class and the Consumer class, each of them implements the Runnable interface and overrides the run()method.

public class Producer implements Runnable{
    private ShareResource resource=null;
    public Producer(ShareResource resource){
        this.resource=resource;
    }

    @Override
    public void run() {
        for (int i=0;i<50;i++){
            if (i%2==0){
                resource.push("Jack","male");
            }else{
                resource.push("Jane","female");
            }
        }
    }
}

public class Consumer implements Runnable {
    private ShareResource resource=null;

    public Consumer(ShareResource resource){
        this.resource=resource;
    }

    @Override
    public void run() {
        resource.pop();
    }
}
Finally, I have the class that runs the main method:

public class Driver {
    public static void main(String[] args){
        ShareResource resource=new ShareResource();
        new Thread(new Producer(resource)).start();
        new Thread(new Consumer(resource)).start();

    }
}

When I run the program, it only prints "Jack Male" once and nothing else. I assume there might be a block but I don't know where. Please help me about this!

LeticiaS
  • 11
  • 2
  • I suggest that you create a thread dump while the program is running (in the stuck state) and edit the thread dump into your question. The thread dump will indicate what exactly each thread is waiting for. This information will be very helpful in answering your question. See https://stackoverflow.com/questions/12277091/what-is-the-meaning-of-thread-dump for more information on taking a thread dump. – Rob Sep 13 '18 at 20:44

1 Answers1

1

Your consumer only calls pop() once so you only get one result. If you take a thread dump you should be able to see the Producer is running and the Consumer isn't running.

I suggest calling pop() 50 times as you are passing 50 messages.

A better approach is to pass a special "poison pill" to let the consumer know there is no more data.

You should be able to write this without the calls to sleep

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130