AnOldSoul
AnOldSoul

Reputation: 4207

Why does the line below the lock wait get executed though wait has been specified?

I have written the following code where the start method is supposed to wait until the stop method notifies it. But during the execution the log line below the start method gets printed though I have specified it to wait. Below shown is my start method implementation is as follows.

private static boolean stopThread = false;

public static void start(String[] args) {
    startThread();
    synchronized (serviceThread) {
        try {
            while(stopThread) {
            serviceThread.wait();
            }
            LOGGER.log(Level.INFO, "Thread: Just after wait method");

        } catch (InterruptedException e) {
            LOGGER.log(Level.INFO, "'Wait' interrupted: " + e.getMessage());
        }
    }
}

Below shown is my stop method implementation.

public static void stop(String[] args) {

    if (serviceThread != null) {
        LOGGER.log(Level.INFO, "Stopping the thread");
        serviceThread.interrupt();
        LOGGER.log(Level.INFO, "Thread: Successfully interrupted");
        synchronized (serviceThread) {
            LOGGER.log(Level.INFO, "About to notify");
            serviceThread.notify();
            stopThread = true;
        }
        stopPlugins();
        kubeLogManager.closeLogger();
        messageBus.terminateMessageBus();
        System.exit(0);
    } else {
        LOGGER.log(Level.INFO, "No thread to interrupt");
    }
}

Why does that log line below the wait method get printed even before the stop method has been called? Please advice.

Upvotes: 0

Views: 64

Answers (1)

Matt Timmermans
Matt Timmermans

Reputation: 59263

See the documentation for Object.wait:

https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()

interrupts and spurious wakeups are possible, and this method should always be used in a loop:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }

You should use a variable to indicate when stop() has been called, and set it before you call notify(). Also, it's safer to use notifyAll(), since it still works if you somehow get another thread waiting on the object.

Upvotes: 1

Related Questions