faridghar
faridghar

Reputation: 1515

Signal Condition With No Waiting Threads

I'm using a ReentrantLock along with a Condition to synchronise two threads. Whenever the consumer threads performs an await() on the condition before the producer thread performs a signal(), things seem to work fine. However, when the producer thread performs a signal() before the consumer thread performs an await(), then the consumer thread just ends up waiting for ever. Is this supposed to happen or am I doing something wrong? What is the expected behaviour when a condition is signalled and there are no waiting threads?

Here's the code for the consumer:

this.lock.lock();
Log.d("websocket", "Sender acquired lock");
try
{
    Log.d("websocket", "Sender waiting for message from server");
    this.resultReady.await();
    Log.d("websocket", "Sender waking up");
    return this.result;

} catch (InterruptedException e)
{
    e.printStackTrace();
}
finally {
    this.lock.unlock();
}

Here's the code for the producer:

Log.d("websocket", "Receiver acquiring lock");
this.lock.lock();
Log.d("websocket", "Receiver acquired lock");
try
{
    Log.d("websocket", "Receiver setting result");
    result = serviceResult;
    Log.d("websocket", "Receiver waking up waiting threads");
    this.resultReady.signal();
} finally
{
    this.lock.unlock();
}

Upvotes: 2

Views: 2250

Answers (1)

markspace
markspace

Reputation: 11030

Is this supposed to happen or am I doing something wrong? What is the expected behaviour when a condition is signalled and there are no waiting threads?

That's supposed to happen. There's no effect if there's no threads waiting. The Java doc says:

Wakes up one waiting thread.

If any threads are waiting on this condition then one is selected for waking up. That thread must then re-acquire the lock before returning from await.

Surely if there's no threads to wake up, then there is no effect?

You have a buffer, which contains one item, your result. You must test this result to be valid independently of the await() method. Or switch to something like a Semaphore which does have an internal state you can set.

// Consumer
this.lock.lock();
Log.d("websocket", "Sender acquired lock");
try
{
    Log.d("websocket", "Sender waiting for message from server");
    while( result == null )   // CHANGE HERE
        resultReady.await();
    Log.d("websocket", "Sender waking up");
    return this.result;

} catch (InterruptedException e)
{
    e.printStackTrace();
}
finally {
    this.lock.unlock();
}

Upvotes: 3

Related Questions