0

My function has to return data just after my thread end, I am using the wait() method after start() my thread but it doesn't work :

private class getDataThread extends Thread {
    @Override
    public void run() {
        super.run();
        while (true) {
            try {
                // ...
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // ...
            }
        }
    }
}

public void getSensorValues(Bundle bundle) {
    // ...
    getDataThread gdt = new getDataThread();
    gdt.start();
    try {
        gdt.wait();
    } catch (InterruptedException e) {
        // ...
    }
}

in LogCat :

: An exception occurred during execution !
: Exception caught: java.lang.reflect.InvocationTargetException
: Exception cause: (SYSTEM) java.lang.IllegalMonitorStateException: object not locked by thread before wait() in getSensorValues
: status::FAILURE - output:: Possible errors: (SYSTEM) java.lang.IllegalMonitorStateException: object not locked by thread before wait() in getSensorValues.

What I'm doing wrong?

Bibix
  • 335
  • 2
  • 4
  • 13

2 Answers2

4

You're looking for join, not wait:

public void getSensorValues(Bundle bundle) {
    // ...
    getDataThread gdt = new getDataThread();
    gdt.start();
    try {
        gdt.join();
    } catch (InterruptedException e) {
        // ...
    }
}

wait has a different purpose, which is to signal another thread that an event has occurred. It requires a matching call to notify. Furthermore, you need to acquire the lock on the object which is being used to wait/notify, which is why you are getting that exception.

And another thing: starting a thread and then immediately joining it is redundant. You might as well execute everything on the main thread.

Tudor
  • 61,523
  • 12
  • 102
  • 142
  • Is `thread.join()` safe to call on main thread? I believe it will block the main thread! – Muhammad Babar Aug 13 '15 at 06:00
  • @Muhammad Babar: Not on the main thread, no. In fact calling `join` immediately after calling `start` makes no sense bacause there is no parallel execution. – Tudor Aug 13 '15 at 11:46
  • @Tudor so what is the correct way to make `UI Thread` wait until `worker thread` completed its run. – Muhammad Babar Aug 13 '15 at 12:01
  • 1
    @Muhammad Babar: You don't want to make the UI thread wait for a worker thread under any circumstances, because that makes it unresponsive to the user. Ideally the worker thread would do its business in the background and then update the UI asynchronously using whatever mechanism the UI framework allows. – Tudor Aug 13 '15 at 15:08
1

wait() does not wait for a thread to finish. It waits for another thread to call notify() or notifyAll().

Instead, you need to use join() so that the other thread will join the current thread. The current thread will block until the other thread finishes.

That said, both wait() and notify() need to be inside a synchronized block for the object being used. Example:

synchronized (lock) {
    lock.wait();
}
mparaz
  • 2,049
  • 3
  • 28
  • 47