I was going through threads and I read that ..The notify() method is used to send a signal to one and only one of the threads that are waiting in that same object's waiting pool.
The method notifyAll() works in the same way as notify(), only it sends the signal to all of the threads waiting on the object.
Now my query is that if Lets say I have 5 threads waiting and through Notify() , i want to send to notification to thread 3 only, what logic should be there that notification is sent to thread 3 only ..!!
You can't directly do this with wait and notify. You'd have to set a flag somewhere, have the code in the thread check it and go back to waiting if it's the wrong thread, and then call notifyAll.
Note that if you have to deal with this, it might be a sign that you should restructure your code. If you need to be able to notify each individual thread, you should probably make each of them wait on a different object.
wait-notify is rather a low level mechanism to indicate to other threads that an event (being expected occured). Example of this is producer/consumer mechanism.
It is not a mechanism for threads to communicate to each other.
If you need something like that you are looking in the wrong way.
The following code starts up five threads and sets the third one a flag which tells it that it is the only to continue. Then all of the threads that are waiting on the same lock object lock are notified (woken-up), but only the one selected continues. Be careful, writing multi-threaded applications is not easy at all (proper synchronization, handling the spurious wake-ups, etc.) You should not need to wake up only one particular thread from the group as this points to an incorrect problem decomposition. Anyway, here you go...
package test;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.start(5);
}
private void start(int n) {
MyThread[] threads = new MyThread[n];
for (int i = 0; i < n; i++) {
threads[i] = new MyThread();
/* set the threads as daemon ones, so that JVM could exit while they are still running */
threads[i].setDaemon(true);
threads[i].start();
}
/* wait for the threads to start */
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
/* tell only the third thread that it is able to continue */
threads[2].setCanContinue(true);
/* wake up all threads waiting on the 'lock', but only one of them is instructed to continue */
synchronized (lock) {
lock.notifyAll();
}
/* wait some time before exiting, thread two should be able to finish correctly, the others will be discarded with the end of the JVM */
for (int i = 0; i < n; i++) {
try {
threads[i].join(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("Done!");
}
/** synchronization object, i.e. a lock which makes sure that only one thread can get into "Critical Section" */
private final Object lock = new Object();
/** A simple thread to demonstrate the issue */
private final class MyThread extends Thread {
private volatile boolean canContinue;
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + " going to wait...");
synchronized (lock) {
while (!canContinue) {
try {
lock.wait(1000); /* one second */
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
System.out.println(Thread.currentThread().getName() + " woken up!");
}
public void setCanContinue(boolean canContinue) {
this.canContinue = canContinue;
}
};
}
The output of the code is:
Thread-0 going to wait...
Thread-2 going to wait...
Thread-3 going to wait...
Thread-1 going to wait...
Thread-4 going to wait...
Thread-2 woken up!
Done!
So you can clearly see that only the third thread (indexed from zero) is woken up. You have to study the Java synchronization and multi-threading in more detail to understand every particular line of the code (for example, here).
I would like to help you more, but I would have to write almost a book about Java threads and that is why I just pointed out to this Java Tutorial on threads. You are right, this problematics is not easy at all, especially for beginners. So I advise you to read through the referenced tutorial and then you should be able to understand most of the code above. There is no easy way around or at least I do not know of any.
Related
I know that the synchronize(LOCK) is unfair, which means there is no guarantee that the longest waiting thread will win the lock. However in my little experiment below it seems that the lock was acquired by shortest waiting threads...
public class Demo {
public static final Object LOCK = new Object();
public void unfairDemo(){
// Occupy the lock for 2 sec
new Thread(() -> {
synchronized (LOCK) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
// Spawn 10 new threads, each with 100ms interval, to see which can win the lock
// If lock is fair then it should print the i in asc order
for (var i = 0; i < 10; i++) {
int finalI = i;
new Thread(() -> {
System.out.println("Added " + String.valueOf(finalI) + "th element to wait for lock");
synchronized (LOCK) {
System.out.println("I got the lock, says " + String.valueOf(finalI) + "-th thread");
}
}).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
// Keep the program alive
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Running unfairDemo() prints the following:
Added 0th element to wait for lock
Added 1th element to wait for lock
Added 2th element to wait for lock
Added 3th element to wait for lock
Added 4th element to wait for lock
Added 5th element to wait for lock
Added 6th element to wait for lock
Added 7th element to wait for lock
Added 8th element to wait for lock
Added 9th element to wait for lock
I got the lock, says 9-th thread
I got the lock, says 8-th thread
I got the lock, says 7-th thread
I got the lock, says 6-th thread
I got the lock, says 5-th thread
I got the lock, says 4-th thread
I got the lock, says 3-th thread
I got the lock, says 2-th thread
I got the lock, says 1-th thread
I got the lock, says 0-th thread
I expected that the order would be scrambled, but no matter how I tried the results are in reverse order. What did I do wrong here?
There are many sources, such as this, that already indicate that there should be no assumption regarding the order in which threads acquire locks. But it doesn't mean the order has to be scrambled.
It probably depends at the very least on the JVM implementation. For example, this document about HotSpot says:
Contended synchronization operations use advanced adaptive spinning techniques to improve throughput even for applications with significant amounts of lock contention. As a result, synchronization performance becomes so fast that it is not a significant performance issue for the vast majority of real-world programs.
...
In the normal case when there's no contention, the synchronization operation will be completed entirely in the fast-path. If, however, we need to block or wake a thread (in monitorenter or monitorexit, respectively), the fast-path code will call into the slow-path. The slow-path implementation is in native C++ code while the fast-path is emitted by the JITs.
I'm not an expert on HotSpot (maybe someone else can provide a more authoritative answer), but based on the C++ code, it looks like the contending threads will be pushed onto a LIFO structure, which may explain the stack-like order you observed:
// * Contending threads "push" themselves onto the cxq with CAS
// and then spin/park.
...
// Cxq points to the set of Recently Arrived Threads attempting entry.
// Because we push threads onto _cxq with CAS, the RATs must take the form of
// a singly-linked LIFO.
What did I do wrong here?
You do all right.
Your expirement shows program execution order in this particular case. Java do not guarantee any order of threads execution without special efforts from programmer's side.
Try this to see chaos:
public class Demo {
public static final Object LOCK = new Object();
public void unfairDemo() {
createThread(0).start();
for (var i = 1; i < 5; i++) {
createThread(i).start();
}
}
private static Thread createThread(final int number) {
return new Thread(() -> {
System.out.println("Added " + number + "th element to wait for lock");
synchronized (LOCK) {
System.out.println("I got the lock, says " + number + "-th thread");
try {
Thread.sleep(number == 0 ? 2000 : 100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
});
}
public static void main(String[] args) {
new Demo().unfairDemo();
}
}
I am trying to achieve this: Created two different threads, one prints odd numbers, one prints even numbers. Once one thread prints a number, it has to wait for the other thread and so on, that is one-after-other.
To achieve this, i am using synchronized block along with wait() and notify().
I am creating a class whose's object will be used to pass to synchronized block in both the threads.
Here is the code:
--> This is used object which will be passed to synchronized block.
package com.vipin.multithread.variousdemos;
public class SyncObject {
public SyncObject () {
}
}
Odd Thread:
package com.vipin.multithread.variousdemos;
public class OddThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int odd_nums[] = {1,3,5,7,9};
public OddThread(SyncObject so) {
t = new Thread(this,"Odd Thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while (true) {
synchronized(so) {
System.out.println("Odd num is --->" + odd_nums[index]);
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
so.notify();
if(index>=5) {
return;
}
}
}
}
}
Even Thread: UPDATE
package com.vipin.multithread.variousdemos;
public class EvenThread implements Runnable {
private Thread t;
int index=0;
SyncObject so=null;
int even_nums[] = {2,4,6,8,10};
public EvenThread(SyncObject so) {
t = new Thread(this, "Even thread");
this.so = so;
t.start();
}
public Thread getThreadInstance() {
return t;
}
#Override
public void run() {
while(true) {
synchronized(so) {
System.out.println("Even num is --->" + even_nums[index]);
so.notify(); <-- Here we are notifying.
try {
so.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
index++;
//so.notify(); <-- commented out.
if(index>=5) {
break;
}
}
}
}
}
Main Application:
package com.vipin.multithread.variousdemos;
public class EvenOddDemo {
public static void main(String[] args) throws InterruptedException {
SyncObject so = new SyncObject();
OddThread ot = new OddThread(so);
EvenThread et = new EvenThread(so);
System.out.println("\nIn main thread");
Thread.sleep(1000000000);
System.out.println("Exiting main thread...");
}
}
---> As seen in the code, I am creating two threads to print even and odd numbers. I am using synchronized block, and passing object of type ==> SyncObject.
SyncObject I am passing as argument to these different threads in main.
However, this programs halts, i.e stuck only first statement gets executed, and then it waits forever:
Here is the output:
Odd num is --->1
In main thread
Even num is --->2
I am not able to understand why this program waits for ever, I am using SAME object on which we are invoking synchronized(), wait() and notify(). As per my understanding, it should work, not sure why this is not working.
Any clues as to why this is waiting forever.
UPDATE:
I did some changes in the code, UPDATE and it works fine.
I still have some doubt. Does notify() be called by the thread even if it has not locked the monitor, like in my case after i updated the code.
Sequence of events:
Odd thread gets executed first, then it calls wait() <-- it releases the monitor and now in sleep mode.
Even thread runs, prints msg, and calls notify() <-- here i am not having clear understanding.
When Even thread calls notify(), at that point it has the monitor, so when it calls notify(), does is still own the monitor?
Now, after Even thread calls notify(), then Odd thread gets notified, and hence it starts execution from the point it was sleeping. It is doing some execution and calls notify(), at that points I presume Odd thread is NOT owning the monitor, it calls notify(). So, my question is, does notify() work same whether or not the thread owns the monitor?
It is only when one do the code, one really understands this. I read book and i felt i understood everything, and seems i am back to square one!
The problem here is simply that both threads go straight into wait. Thread 1 gets so, prints value then waits. Thread 2 then gets so, prints value then waits. So both are sleeping away, since nobody is there to notify them. So, a simple fix would be to do so.notify(), right before so.wait(). Then they're not infinitely waiting.
EDIT
Odd thread starts, executes & then waits. Then even thread starts, executes, notifies & then waits. Even thread holds the lock over the monitor until it goes into wait.
When the even thread called on notify, the odd thread awakens & polls for the lock. Once the even thread goes into wait (& releases the lock), then the odd thread can obtain the lock.
If the even thread had not called on notify, then the odd thread would continue to sleep. The even thread would have gone to wait & released the lock. No thread is polling or attempting to obtain the lock, hence the program remains in the suspended state.
The documentation also provides a similar explanation. I hope that clears your doubts.
all. I have a question for Java wait-notify mechanism. The answer is is there a guaranty that the threads will be executed in this order - from last to the first etc. the result always will be 100, 99, ... , 1 ? This is the snippet of code:
public class Main {
static int counter = 0;
static Object o = new Object();
public static void main(String[] args){
for(int i = 0; i < 100; ++i){
new Thread(() -> {
synchronized (o) {
try {
int c = ++counter;
o.wait();
System.out.println("" + c);
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o) {
new Thread(()-> {
synchronized(o){
System.out.println("LAsttttttttttttttttt");
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
o.notifyAll();
}
}
}
I run it 10 times and the result is always the same. I coudn't find anything about this in internet. And one more question - when we have 100 threads waiting, when we notifyAll, is there a guaranty that first one of waiting threads will be executed, after then a second one and after all 100 waiting threads are executed, other waiting methods(which were in synchronized block, but don't have wait() in their body), will be executed after that (after all 100 threads that were waiting are executed). Or notifyAll only guaranty that all waiting threads will start fighting with every method which is synchronized by this object? I thing that this is the answer :
"The awakened threads will not be able to proceed until the current
* thread relinquishes the lock on this object. The awakened threads
* will compete in the usual manner with any other threads that might
* be actively competing to synchronize on this object; for example,
* the awakened threads enjoy no reliable privilege or disadvantage in
* being the next thread to lock this object."
But I want to be sure that I understand what's going on when we have wait-notify.
Thanks in advance.
No . .there is no guarantee that a set of awoken threads will be executed in any particular order. (This may happen in order because of a particular implementation of JVM or the speed of the computer the program is run on, or many other load based variables. However, there is no language guarantee.)
Java's synchronized code block makes no guarantee about the sequence in which threads waiting to enter the synchronized block are allowed to enter, and notifyAll() doesn't present itself as a special case.
As you have seen in notifyAll() javadoc (emphasis mine):
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.
I was trying to implement something similar to Java's bounded BlockingQueue interface using Java synchronization "primitives" (synchronized, wait(), notify()) when I stumbled upon some behavior I don't understand.
I create a queue capable of storing 1 element, create two threads that wait to fetch a value from the queue, start them, then try to put two values into the queue in a synchronized block in the main thread. Most of the time it works, but sometimes the two threads waiting for a value start seemingly waking up each other and not letting the main thread enter the synchronized block.
Here's my (simplified) code:
import java.util.LinkedList;
import java.util.Queue;
public class LivelockDemo {
private static final int MANY_RUNS = 10000;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < MANY_RUNS; i++) { // to increase the probability
final MyBoundedBlockingQueue ctr = new MyBoundedBlockingQueue(1);
Thread t1 = createObserver(ctr, i + ":1");
Thread t2 = createObserver(ctr, i + ":2");
t1.start();
t2.start();
System.out.println(i + ":0 ready to enter synchronized block");
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
t1.join();
t2.join();
System.out.println();
}
}
public static class MyBoundedBlockingQueue {
private Queue<Object> lst = new LinkedList<Object>();;
private int limit;
private MyBoundedBlockingQueue(int limit) {
this.limit = limit;
}
public synchronized void addWhenHasSpace(Object obj) throws InterruptedException {
boolean printed = false;
while (lst.size() >= limit) {
printed = __heartbeat(':', printed);
notify();
wait();
}
lst.offer(obj);
notify();
}
// waits until something has been set and then returns it
public synchronized Object getWhenNotEmpty() throws InterruptedException {
boolean printed = false;
while (lst.isEmpty()) {
printed = __heartbeat('.', printed); // show progress
notify();
wait();
}
Object result = lst.poll();
notify();
return result;
}
// just to show progress of waiting threads in a reasonable manner
private static boolean __heartbeat(char c, boolean printed) {
long now = System.currentTimeMillis();
if (now % 1000 == 0) {
System.out.print(c);
printed = true;
} else if (printed) {
System.out.println();
printed = false;
}
return printed;
}
}
private static Thread createObserver(final MyBoundedBlockingQueue ctr,
final String name) {
return new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println(name + ": saw " + ctr.getWhenNotEmpty());
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
}, name);
}
}
Here's what I see when it "blocks":
(skipped a lot)
85:0 ready to enter synchronized block
85:0 entered synchronized block
85:2: saw hello
85:1: saw world
86:0 ready to enter synchronized block
86:0 entered synchronized block
86:2: saw hello
86:1: saw world
87:0 ready to enter synchronized block
............................................
..........................................................................
..................................................................................
(goes "forever")
However, if I change the notify() calls inside the while(...) loops of addWhenHasSpace and getWhenNotEmpty methods to notifyAll(), it "always" passes.
My question is this: why does the behavior vary between notify() and notifyAll() methods in this case, and also why is the behavior of notify() the way it is?
I would expect both methods to behave in the same way in this case (two threads WAITING, one BLOCKED), because:
it seems to me that in this case notifyAll() would only wake up the other thread, same as notify();
it looks like the choice of the method which wakes up a thread affects how the thread that is woken up (and becomes RUNNABLE I guess) and the main thread (that has been BLOCKED) later compete for the lock — not something I would expect from the javadoc as well as searching the internet on the topic.
Or maybe I'm doing something wrong altogether?
Without looking too deeply into your code, I can see that you are using a single condition variable to implement a queue with one producer and more than one consumer. That's a recipe for trouble: If there's only one condition variable, then when a consumer calls notify(), there's no way of knowing whether it will wake the producer or wake the other consumer.
There are two ways out of that trap: The simplest is to always use notifyAll().
The other way is to stop using synchronized, wait(), and notify(), and instead use the facilities in java.util.concurrent.locks.
A single ReentrantLock object can give you two (or more) condition variables. Use one exclusively for the producer to notify the consumers, and use the other exclusively for the consumers to notify the producer.
Note: The names change when you switch to using ReentrantLocks: o.wait() becomes c.await(), and o.notify() becomes c.signal().
There appears to be some kind of fairness/barging going on using intrinsic locking - probably due to some optimization. I am guessing, that the native code checks to see if the current thread has notified the monitor it is about to wait on and allows it to win.
Replace the synchronized with ReentrantLock and it should work as you expect it. The different here is how the ReentrantLock handles waiters of a lock it has notified on.
Update:
Interesting find here. What you are seeing is a race between the main thread entering
synchronized (ctr) {
System.out.println(i + ":0 entered synchronized block");
ctr.addWhenHasSpace("hello");
ctr.addWhenHasSpace("world");
}
while the other two thread enter their respective synchronized regions. If the main thread does not get into its sync region before at least one of the two, you will experience this live-lock output you are describing.
What appears to be happening is that if both the two consumer threads hit the sync block first they will ping-pong with each other for notify and wait. It may be the case the JVM gives threads that are waiting priority to the monitor while threads are blocked.
Suppose that I have an arraylist called myList of threads all of which are created with an instance of the class myRunnable implementing the Runnable interface, that is, all the threads share the same code to execute in the run() method of myRunnable. Now suppose that I have another single thread called singleThread that is created with an instance of the class otherRunnable implementing the Runnable interface.
The synchornization challenge I have to resolve for these threads is the following: I need all of the threads in myList to execute their code until certain point. Once reached this point, they shoud sleep. Once all and only all of the threads in myList are sleeping, then singleThread should be awakened (singleThread was already asleep). Then singleThread execute its own stuff, and when it is done, it should sleep and all the threads in myList should be awakened. Imagine that the codes are wrapped in while(true)'s, so this process must happen again and again.
Here is an example of the situation I've just described including an attempt of solving the synchronization problem:
class myRunnable extends Runnable
{
public static final Object lock = new Object();
static int count = 0;
#override
run()
{
while(true)
{
//do stuff
barrier();
//do stuff
}
}
void barrier()
{
try {
synchronized(lock) {
count++;
if (count == Program.myList.size()) {
count = 0;
synchronized(otherRunnable.lock) {
otherRunnable.lock.notify();
}
}
lock.wait();
}
} catch (InterruptedException ex) {}
}
}
class otherRunnable extend Runnable
{
public static final Object lock = new Object();
#override
run()
{
while(true)
{
try {
synchronized(lock) {
lock.wait();
} catch (InterruptedException ex) {}
// do stuff
try {
synchronized(myRunnable.lock) {
myRunnable.notifyAll();
}
}
}
}
class Program
{
public static ArrayList<Thread> myList;
public static void main (string[] args)
{
myList = new ArrayList<Thread>();
for(int i = 0; i < 10; i++)
{
myList.add(new Thread(new myRunnable()));
myList.get(i).start();
}
new Thread(new OtherRunnable()).start();
}
}
Basically my idea is to use a counter to make sure that threads in myList just wait except the last thread incrementing the counter, which resets the counter to 0, wakes up singleThread by notifying to its lock, and then this last thread goes to sleep as well by waiting to myRunnable.lock. In a more abstract level, my approach is to use some sort of barrier for threads in myList to stop their execution in a critical point, then the last thread hitting the barrier wakes up singleThread and goes to sleep as well, then singleThread makes its stuff and when finished, it wakes up all the threads in the barrier so they can continue again.
My problem is that there is a flaw in my logic (probably there are more). When the last thread hitting the barrier notifies otherRunnable.lock, there is a chance that an immediate context switch could occur, giving the cpu to singleThread, before the last thread could execute its wait on myRunnable.lock (and going to sleep). Then singleThread would execute all its stuff, would execute notifyAll on myRunnable.lock, and all the threads in myList would be awakened except the last thread hitting the barrier because it has not yet executed its wait command. Then, all those threads would do their stuff again and would hit the barrier again, but the count would never be equal to myList.size() because the last thread mentioned earlier would be eventually scheduled again and would execute wait. singleThread in turn would also execute wait in its first line, and as a result we have a deadlock, with everybody sleeping.
So my question is: what would be a good way to synchronize these threads in order to achieve the desired behaviour described before but at the same time in a way safe of deadlocks??
Based on your comment, sounds like a CyclicBarrier would fit your need exactly. From the docs (emphasis mine):
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
Unfortunately, I haven't used them myself, so I can't give you specific pointers on them. I think the basic idea is you construct your barrier using the two-argument constructor with the barrierAction. Have your n threads await() on this barrier after this task is done, after which barrierAction is executed, after which the n threads will continue.
From the javadoc for CyclicBarrier#await():
If the current thread is the last thread to arrive, and a non-null barrier action was supplied in the constructor, then the current thread runs the action before allowing the other threads to continue. If an exception occurs during the barrier action then that exception will be propagated in the current thread and the barrier is placed in the broken state.