JAVA waking up threads in specific order - java

Let's say that i have 10 active threads and only 3 resources (of something)
while the first three threads got the resources i want all other thread that try to get the resource to wait but that the wake up or notify will be in f.i.f.o order i mean that the first thread that got the waiting will be the first to wake up.
thank you all.

I think this link explains it quite well: https://www.safaribooksonline.com/library/view/java-threads-second/1565924185/ch04s03.html
When using notify it is impossible to decide or determine in advance which thread will be allowed to execute. I see 2 solutions to this:
Use notifyAll() and let each thread check for itself whether whose turn it is (e.g. by using a synchronised FIFO queue)
Use the method described in the link: let each thread wait on a different object and use 1 thread that has as it's sole purpose to notify the correct object. This seems like the best solution to me.

Java generally doesn't decide these things however if you use a fair lock e.g.
Lock lock = new ReentrantLock(true);
then those threads will acquire the lock in the order they were attempted. This works by disregarding the order thread would be notified and ensuring a lock which is not taken unless the thread is next on the FIFO queue.

Related

Does lock.wait(1) *guarantee* that threads competing over the lock will grab it in this time?

I have a controller thread that is permanently in synchronized(lock): It does a calculation step, then it does wait(1000), then it checks if more work is to be done. If so, it does another step and waits(1000). If not, it just waits(1000) straightaway. (Mind that I'm using wait, not sleep.)
Sometimes, the calculation steps called by the controller ask the controller to call them many times in a row - that's a high performance mode lasting for multiple seconds. During this time, no other thread (e.g. Swing) could alter data used by this controller thread. Swing would now hang if it tried to do this!
I want to keep the balance between high performance and good fluidity.
Therefore, I want to add wait(1) in this high performance mode loop.
QUESTION: Will a thread waiting to grab the lock achieve dominance with ABSOLUTE certainty, if I sprinkle these wait(1) calls into the calculation loop?
QUESTION: Will a thread waiting to grab the lock achieve dominance with ABSOLUTE certainty, if I sprinkle these wait(1) calls into the calculation loop?
The short answer is sort of in that you are always getting the lock when lock.wait(1) returns. However, I don't think you understand how to use lock and notify to gain control over a shared resource. To call lock.wait(1) you need to own the lock to start with.
The call releases the lock and returns either if lock.notify() or notifyAll() was called or if the timeout expires and (NOTE) the lock is available to be locked again. This means that if someone else owns the lock for a long period of time, the wait(...) method won't return unless the lock is released – which could be for many milliseconds. It is designed to help threads coordinate between themselves.
If the question is "does calling wait(1) in a calculation loop only give the lock to other people for 1ms" then the answer is no.
If you have a resource that can only be used by one thread at a time then the other threads will need to wait until it is available. You hope that each thread uses the resource for a short amount of time so the waiting is small.
You can protect the resource using a couple of different mechanisms. The easiest is to just put a synchronized block around its use. This protects it from race conditions and ensures that any changes to the resource gets published to main memory in all threads. No wait or notify calls are required using this mechanism.
Another way of doing it is to use lock.wait(...) and lock.notify(). This mechanism is required when (for example) threads are consuming from a collection and need to wait for there to be entities added. In this case, when a thread adds an entity to the collection it calls lock.notify() and any thread(s) waiting for work in lock.wait() will be notified that there is work to do and will awaken.
The use of the lock.wait(...) timeout argument means that threads can wait for a certain amount of time for the resource to be available before giving up. In the queue processing example above, the threads may need to check if the application is shutting down every second or so. So they call lock.wait(1000), test if the shutdown flag has been set, and if not they can check for work to be done and then call wait again. Just because you are calling lock.wait(1) doesn't ensure any sort of lock "dominance" and doesn't mean that the method returns after 1ms.
If you want to use wait and notify signaling then you would need a secondary variable to check to see if the resource is in use. The following example uses an inUse boolean field.
private final Object lock = new Object();
private boolean inUse = false;
...
synchronized (lock) {
while (inUse) {
lock.wait();
}
inUse = true;
}
// use the resource
...
synchronized (lock) {
inUse = false;
lock.notify();
}
Notice that the example tests for inUse in a while loop and not just an if. This is an important pattern and is needed because you could be notified but another thread might have gotten access to the resource while you were waiting.

Difference between Locks and .join() method

Let's say you have two threads, thread1 and thread2. If you call thread1.start() and thread2.start() at the same time and they both print out numbers between 1 and 5, they will both run at the same time and they will randomly print out the numbers in any order, if I am not mistaken. To prevent this, you use the .join() method to make sure that a certain thread gets executed first. If this is what the .join() method does, what is the Lock object used for?
Thread.join is used to wait for another thread to finish. The join method uses the implicit lock on the Thread object and calls wait on it. When the thread being waited for finishes it notifies the waiting thread so it can stop waiting.
Java has different ways to use locks to protect access to data. There is implicit locking that uses a lock built into every Java object (this is where the synchronized keyword comes in), and then there are explicit Lock objects. Both of them protect data from concurrent access, the difference is the explicit Locks are more flexible and powerful, while implicit locking is designed to be easier to use.
With implicit locks, for instance, I can't not release the lock at the end of a synchronized method or block, the JVM makes sure that the lock gets released as the thread leaves. But programming with implicit locks can be limiting. For instance, there aren't separate condition objects so if there are different threads accessing a shared object for different things, notifying only a subset of them is not possible.
With explicit Locks you get separate condition objects and can notify only those threads waiting on a particular condition (producers might wait on one condition while consumers wait on another, see the ArrayBlockingQueue class for an example), and you can implement more involved kinds of patterns, like hand-over-hand locking. But you need to be much more careful, because the extra features introduce complications, and releasing the lock is up to you.
Locking typically prevents more than one thread from running a block of code at the same time. This is because only ONE thread at a time can acquire the lock and run the code within. If a thread wants the lock but it is already taken, then that thread goes into a wait state until the lock is released. If you have many threads waiting for the lock to be released, which one gets the lock next is INDETERMINATE (can't be predicted). This can lead to "thread starvation" where a thread is waiting for the lock, but it just never gets it because other threads always seem to get it instead. This is a very generic answer because you didn't specify a language. Some languages may differ slightly in that they might have a determinate method of deciding who gets the lock next.

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?
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.
I think the thread calls await() first will be triggered first , and the conclusion comes from the source code.
What did await() do ?
create a wait node and add the node to a fifo queue maintained by Condition
release the lock, you see before you call await(),you need to call lock.lock()
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.
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.

wait() , notify() - which thread first unlock?

Trying to understand wait() and notify(). I know when thread A went to wait() it will be waked up by notify() from other thread.
But what will happens if threads A,B,C went to wait() in represented order? Who will be waked up by notify()? According to my experiments A thread will be waked up at first. I'm right?
Does it means that system knows in which order threads went to wait() ?
From the documentation for notify(), emphasis mine:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
Some other APIs, such as Semaphore, have a concept of "fairness", where you can ensure that threads do proceed in the order in which they blocked.
Section 17.2.2 Notification of Java Language Specification:
There is no guarantee about which thread in the wait set is selected.
So, observed behavior is not guaranteed and should not be relied upon.
No, the VM does not know in which order the threads were put in Waiting state.
When you call notify(), one of them will be back to Alive/Runnable state and there is no way to know which one the VM will choose.
Sometimes they can run in the order they were put in Waiting state, but the specification does not guarantee that. So in a different VMs you can have a completely different results or even in the same VM, if you run the code multiple times.
No, there is no guarantee about the order. The javadoc of the notify method is pretty clear on this:
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
There's no such an order. Either thread has an equal opportunity to get into runnable state. Actually JVM/OS can see them only as a set of waiting threads, they don't know any order.
In terms of your experiment, to get into a fair conclusion, actually you have to perform it for a huge number of times.
In threads, you can expect an order (FIFO), only if you are using something like a strong Semaphore. Then these threads are put into a waiting queue and fist comer would be first served.

Can anyone explain thread monitors and wait?

Someone at work just asked for the reasoning behind having to wrap a wait inside a synchronized.
Honestly I can't see the reasoning. I understand what the javadocs say--that the thread needs to be the owner of the object's monitor, but why? What problems does it prevent? (And if it's actually necessary, why can't the wait method get the monitor itself?)
I'm looking for a fairly in-depth why or maybe a reference to an article. I couldn't find one in a quick google.
Oh, also, how does thread.sleep compare?
edit: Great set of answers--I really wish I could select more than one because they all helped me understand what was going on.
Lots of good answers here already. But just want to mention here that the other MUST DO when using wait() is to do it in a loop dependent on the condition you are waiting for in case you are seeing spurious wakeups, which in my experience do happen.
To wait for some other thread to change a condition to true and notify:
synchronized(o) {
while(! checkCondition()) {
o.wait();
}
}
Of course, these days, I'd recommend just using the new Condition object as it is clearer and has more features (like allowing multiple conditions per lock, being able to check wait queue length, more flexible schedule/interrupt, etc).
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
while (! checkCondition()) {
condition.await();
}
} finally {
lock.unlock();
}
}
If the object does not own the object monitor when it calls Object.wait(), it will not be able to access the object to setup a notify listener until the the monitor is released. Instead, it will be treated as a thread attempting to access a method on a synchronized object.
Or to put it another way, there is no difference between:
public void doStuffOnThisObject()
and the following method:
public void wait()
Both methods will be blocked until the object monitor is released. This is a feature in Java to prevent the state of an object from being updated by more than one thread. It simply has unintended consequences on the wait() method.
Presumably, the wait() method is not synchronized because that could create situations where the Thread has multiple locks on the object. (See Java Language Specifications/Locking for more info on this.) Multiple locks are a problem because the wait() method will only undo one lock. If the method were synchronized, it would guarantee that only the method's lock would be undone while still leaving a potential outer lock undone. This would create a deadlock condition in the code.
To answer your question on Thread.sleep(), Thread.sleep() does not guarantee that whatever condition you are waiting on has been met. Using Object.wait() and Object.notify() allows a programmer to manually implement blocking. The threads will unblock once a notify is sent that a condition has been met. e.g. A read from disk has finished and data can be processed by the thread. Thread.sleep() would require the programmer to poll if the condition has been met, then fall back to sleep if it has not.
It needs to own the monitor, since the purpose of the wait() is to release the monitor and let other threads obtain the monitor to do processing of their own. The purpose of these methods (wait/notify) is to coordinate access to synchronized code blocks between two threads that require each other to perform some functionality. It is not simply a matter of making sure access to a data structure is threadsafe, but to coordinate events between multiple threads.
A classic example would be a producer/consumer case where one thread pushes data to a queue, and another thread consumes the data. The consuming thread would always require the monitor to access the queue, but would release the monitor once the queue is empty. The producer thread would then only get access to write to the thread when the consumer is no longer processing. It would notify the consumer thread once it has pushed more data into the queue, so it can regain the monitor and access the queue again.
Wait gives up the monitor, so you must have it to give it up. Notify must have the monitor as well.
The main reason why you want to do this is to ensure that you have the monitor when you come back from wait() -- typically, you are using the wait/notify protocol to protect some shared resource and you want it to be safe to touch it when wait returns. The same with notify -- usually you are changing something and then calling notify() -- you want to have the monitor, make changes, and call notify().
If you made a function like this:
public void synchWait() {
syncronized { wait(); }
}
You would not have the monitor when wait returned -- you could get it, but you might not get it next.
Here's my understanding on why the restriction is actually a requirement. I'm basing this on a C++ monitor implementation I made a while back by combining a mutex and a condition variable.
In a mutex+condition_variable=monitor system, the wait call sets the condition variable into a wait state and releases the mutex. The condition variable is shared state, so it needs to be locked to avoid race conditions between threads that want to wait and threads that want to notify. Instead of introducing yet another mutex to lock its state, the existing mutex is used. In Java, the mutex is correctly locked when the about-to-wait thread owns the monitor.
Mostly wait is done if there is a condition say a queue is empty.
If(queue is empty)
queue.wait();
Let us assume the queue is empty.
In case if the current thread pre-empts after checking the queue, then if another
thread adds few elements to queue, the current thread will not know and will go for wait
state. Thats wrong.
So we should have something like
Synchornized(queue)
{
if(queue is empty)
queue.wait();
}
Now let us consider what if they made wait itself as synchronized. As already mentioned in one of the comments, it releases only one lock. That means if wait() was synchronized in the above code only one lock would have been released. Implies that current thread will go for wait with the lock for the queue.

Categories