ZACH
ZACH

Reputation: 11

In Java, will multiple threads await() the same condition get unlocked at the same time later?

In Java, if multiple threads await() the same conditionA, then another thread calls signalAll() on conditionA, will all the threads waiting for conditionA get unlocked at the same time?

For example, I have an add and a remove method of a queue:

public void add(E newValue) throws InterruptedException
{
    queueLock.lock();
    try
    {
        while (size == elements.length)
            spaceAvailableCondition.await();
        elements[tail] = newValue;
        tail++;
        size++;
        if (tail == elements.length)
            tail = 0;
        valueAvailableCondition.signalAll();
     }
     finally
     {
         queueLock.unlock();
     }
}

public E remove() throws InterruptedException
{
    queueLock.lock();
    try
    {
        while (size == 0)
            valueAvailableCondition.await();
        E r = (E) elements[head];
        head++;
        size--;
        if (head == elements.length)
            head = 0;
        spaceAvailableCondition.signalAll();
        return r;
    }
    finally
    {
        queueLock.unlock();
    }
}

Suppose multiple threads keep calling add method on a shared queue. After a while, the queue is full. All those threads are stuck at spaceAvailableCondition.awati(). Then, I have this thread that calls the method remove, signalAll() the spaceAvailableCondition. Will all the threads that called add get unlocked and run the method, which will cause a corruption on that queue?

I ask this question because I think all the other 'adding threads' have implemented queueLock.lock(). Then all the thread have ownership of this lock.

Upvotes: 1

Views: 815

Answers (2)

Solomon Slow
Solomon Slow

Reputation: 27115

Assuming that spaceAvailableCondition is a condition variable that was obtained from queueLock, then no, they won't wake up "at the same time".

You already know that you're not allowed to call spaceAvailableCondition() from a thread that doesn't have queueLock locked. That's because, the spaceAvailableCondition.await() call does these things:

  1. It releases queueLock.

  2. It waits for another thread to signal the condition,

  3. It re-acquires queueLock

  4. It returns.

Only one thread can own the queueLock at a time, so when the condition is signalled, only one thread will be able immediately return from the await() call. The next thread will not be able to acquire the lock and return from await() until the first one releases the lock, and so on.

Upvotes: 0

Adrian Shum
Adrian Shum

Reputation: 40036

Not sure if I understand your question right.

Although awaiting threads will be woken up by signalAll(), but only one of them is able to re-acquire the lock (I assume is the queueLock) associated with the spaceAvailableCondition those thread are awaiting at. Hence, only 1 "add" thread is going to execute the logic.

Upvotes: 2

Related Questions