Brijendar Bakchodia
Brijendar Bakchodia

Reputation: 1797

How do Conditions in Java know which Thread to trigger?

I am reading the Condition Documentation from Java and I have a misunderstanding. Reading their example of put and take, as you see they have in the function put the line of code: notEmpty.signal() where notEmpty is a Condition from lock.

What I am wondering if what if there are multiple threads that are waiting for the signal of notEmpty. What happens in this case and which thread is triggered?

Upvotes: 2

Views: 271

Answers (3)

Ohm's Lawman
Ohm's Lawman

Reputation: 393

What I am wondering is, what if there are multiple threads that are waiting for the signal of notEmpty. What happens in this case and which thread is triggered?

As others have already answered, you can not know which thread will be triggered.

so I guess this approach only works for two threads in total?

Depends what "this approach" means. It often does make sense to have several threads awaiting the same condition. The trick is, since you can not know which thread will be awakened, you should write your code in such a way that it does not matter which thread is awakened.

This is an example of a good practice that you should try to follow when you write multi-threaded code, namely: When there's work to be done, it should not matter which thread does the work.

Upvotes: 1

lin
lin

Reputation: 1589

I think the thread calls await() first will be triggered first , and the conclusion comes from the source code.

What did await() do ?

  1. create a wait node and add the node to a fifo queue maintained by Condition
  2. release the lock, you see before you call await(),you need to call lock.lock()
  3. test if signal() was called during step 2 by other thread. if no then park current thread.

What did signal() do ?

  • take a node in the queue maintained by Condition and put it in the queue maintained by Lock, so if one thread call await() first , it will get into Lock's queue first

When will the parked thread be awaken ?

Apparently,Lock.unlock() will be called after Condition.signal(), Lock.unlock() will get one node in Lock's waiting queue from the head to the tail, see AbstractQueuedSynchronizer#unparkSuccessor,so if you enter Lock's queue first, you will be triggered first.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533530

It make a system call to the OS which handles it. The JVM has no idea which thread if any will wake.

Threads are managed by the OS not the JVM so the best it can do is make the right system calls and let the OS do the rest.

Upvotes: 1

Related Questions