Reputation: 1515
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
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