0

I wrote this for my class solution but I don't understand how it works. I thought when you use wait(), your release the lock to other waiting thread. Then the other thread notify() lets the original thread that issued wait() to resume operation. What I don't understand is in the printAlphabet() method, I have to put wait() then notify(). Then for printDigits(), I have to put notify() and then wait().

If I just use wait() in the first one, then notify() on the second one. First, printAlphabet() prints a. Then printDigits() prints 1 and will complete the entire loop. And then printAlphabet() resumes BUT then stuck after printing letter b forever. I even asked my trainer and he couldn't figure it out neither. Appreciate any help.

class Jobs {
    public void printAlphabet() throws Exception {
        char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
        synchronized (this) {
            for (int i = 0; i < alphabet.length; i++) {
                System.out.print(alphabet[i] + " ");
//              System.out.println("Waiting to print digit");
                wait();
                Thread.sleep(1000);
                notify();

            }

        }
    }

    public void printDigits() throws Exception {
        String[] digits = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26".split(" ");
        synchronized (this) {
            for (int i = 0; i < digits.length; i++) {
                System.out.print(digits[i] + " ");
//              System.out.println("Waiting to print alphabet");
                    notify();
                    Thread.sleep(1000);
                    wait();

                

            }

        }
    }

}

public class Day8Problem31 {

    public static void main(String[] args) throws Exception {
        Jobs task = new Jobs();
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    task.printAlphabet();

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {

                try {
                    task.printDigits();

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

        t1.start();
        t2.start();

    }

}
  • Did you read https://stackoverflow.com/a/2537117/5493813 or https://www.baeldung.com/java-wait-notify ? – st.huber Nov 16 '21 at 07:48

1 Answers1

1

Let's put a few facts

  1. wait will immediately suspend a thread and release a lock
  2. notify will resume one blocked thread (by wait), however it won't interrupt in any way execution of current thread, it'll continue

In your case thread executing printDigits method when calling notify will resume thread (blocked by wait in printAlphabet), however that resumed thread is now trying to aquire a lock on "this", which is being held by 2nd thread (still executing printDigits). Only after 2nd thread releases the lock (by leaving synchronized block or calling wait - which will release lock automatically), the first thread will be able to acquire it and continue

Mirek Pluta
  • 7,883
  • 1
  • 32
  • 23