I made this sample to understand how Wait-Notify works:
public class WaitingTest implements Runnable {
Thread b = new Thread();
int total;
public static void main(String[] args){
WaitingTest w = new WaitingTest();
}
public WaitingTest(){
b.start();
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + total);
}
}
#Override
public void run(){
synchronized(b){
for(int i=0; i<100 ; i++){
total += i;
System.out.println(total);
}
b.notify();
}
}
}
But I'm stuck here for hours and I can't understand why it's not quite working. My output should be more than 0, but its always zero...I was wondering if its becuase of the usage of different threads, but Im not really sure..What am I missing?
I think you have some serious holes in your understanding. You've declared a Thread
Thread b = new Thread();
and started it in the constructor
b.start();
That Thread will start and die right away since it has no Runnable attached to it.
It just so happens that when a Thread dies, it calls notify() on itself and since you are synchronized on that same Thread object, your wait()ing thread will be awoken. You also have a race here. If the Thread ends before the main thread reaches the wait(), you will be deadlocked.
Also, there is no reason for run() to be called, which is why total remains 0.
Any object can be synchronized on, it doesn't have to be a Thread. And since Thread has that weird behavior of notify()ing itself, you probably shouldn't use it.
You should go through both the Thread tutorials and the synchronization tutorials.
Apart from the problem with how you have arranged your threads, you have a incorrect use of wait()/notify()
notify() is stateless. If no thread is waiting, nothing will be notified. If you wait() later it will not be notified.
wait() can wake spuriously. Just because wait() woke doesn't mean anything notified it.
This means you need to associate wait/notify with state (in fact it's rather pointless without it)
For example.
// to notify
synchronized(lock) {
signalled = true;
lock.notify();
}
// to wait
synchronized(lock) {
while(!signalled)
lock.wait();
}
Related
This question was asked to me in an interview. Before I had told him this,
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
Consider the snippet:
Q1:
public class Q1 {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
Producer1:
public class Producer1 implements Runnable {
Q1 q;
Producer1(Q1 q) {
this.q = q;
new Thread(this, "Producer").start();
}
#Override
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
Consumer1
public class Consumer1 implements Runnable {
Q1 q;
Consumer1(Q1 q) {
this.q = q;
new Thread(this, "Consumer").start();
}
#Override
public void run() {
while (true) {
q.get();
}
}
}
PC1:
public class PC1 {
public static void main(String args[]) {
Q1 q = new Q1();
new Producer1(q);
new Consumer1(q);
System.out.println("Press Control-C to stop.");
}
}
So, he asked as soon as you have created this thread new Producer1(q), then according to you, the synchronized int get() method must have been locked by the same thread, i.e, by new Producer1(q) when it accessed synchronized int put(). I said yes.
But I checked in eclipse, get is callable by new Consumer1(q). The program works perfect.
Where am I going wrong?
O/P:
The call to wait() will release the monitor for the time waiting.
That's what is documented for Object.wait():
The current thread must own this object's monitor. The thread
releases ownership of this monitor and waits until another thread
notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the
notifyAll method. The thread then waits until it can
re-obtain ownership of the monitor and resumes execution.
Once a thread enters any synchronized method on an instance, no other
thread can enter any other synchronized method on the same instance.
What you forgot to add here is "except if the lock is released".
...and it is the case in your example, when calling wait.
The documentation specify :
The thread releases ownership of this monitor and waits until another
thread notifies threads waiting on this object's monitor to wake up
either through a call to the notify method or the notifyAll method.
Since the lock is released, you step in the other method (and the condition is true because the boolean was modified). Once in the other method, you release the lock again, then call notify and you wake up the old thread which terminates (re-modify boolean to pass the condition in other method, and notify). That way you step between both methods ad-infinitum.
wait() and notify() is acts as a signal between threads, to control the threads to do or to not do the stuff.
The program works perfect because here 2 threads (Producer, Consumer) which fight for the one lock (monitor). When Consumer aquires the lock (Q1 object) then Producer is waiting for the lock. When Consumer finishes his work it release the lock. Consumer releases the lock also when wait() method has been called, because wait() sets thread to Waiting state with lock release. It's time for Producer to aquire the lock and does his work. When Producer thread notify() calls then Consumer continue his work (when aquired the lock). The same is right for Producer.
Resume: Q1 object is a lock for all threads. If it aquired someone then others are blocked and the answer is - it not possible to get an access at the same time to the get(), put() methods more then 2 threads.
I think that the question is ambiguous. (E.g., what does "accessible" mean?)
IMO, a good interview question should not have a right answer and a wrong answer. A good interview question should be a conversation starter, that gives you an opportunity to show how much you know about the subject.
When I am asking the interview questions, I like a candidate who can see through the question, and get down to the underlying mechanism. E.g.,
What the JLS guarantees is that no two threads can be _synchronized_
on the same instance at the same time...
Then we could explore questions like, how could two threads enter the same synchronized method at the same time? (e.g., synchronized on different instances), how could two threads be in the same synchronized method for the same instance at the same time (one of them could be in a wait() call), ...
A thread can not access a synchronized block of code unless it has aquired a lock on the object that guards the block. In your case, the synchronized keyword uses the lock of the object in which it has been declared. So as long as a thread is executing get(), no other thread can execute the put().
If you apply this, when put() sets the value, it notifies consumer which accepts the value. The code should work even after you have removed the wait() and notify() calls from both get and put methods
Why usually threading samples put so many code in synchronized block. According to my understanding in following case synchronized is used just for locking b for wait and notify:
Main class ThreadA :
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
System.out.println(Thread.currentThread().getName());
}
}
}
and class ThreadB:
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this)
{
System.out.println();
for(int i=0;i<100;i++)
{
System.out.println(Thread.currentThread().getName());
total += i;
}
notify();
}
}
}
What will change if I put just wait and notify in synchronized block:
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println("Waiting for b to complete...");
synchronized(b) { b.wait();}
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
System.out.println(Thread.currentThread().getName());
}
}
According to my understanding in following case synchronized is used just for locking b for wait and notify
Your understanding is wrong.
synchronized is also used for:
Mutual exclusion, to ensure that only one thread executes code "guarded" by a particular monitor at a time
Ensuring memory access across threads is correct (that one thread sees changes made by another thread)
What will change if I put just wait and notify in synchronized block:
In this particular case, it will make a difference based on a race condition - in the original code, if the new thread starts executing before the synchronized block is reached in the original thread, it won't get as far as "Waiting for b to complete" until the second thread has finished... at which point it will block forever in wait.
Note that it's a really bad idea to wait on Thread monitors, as wait/notify is used internally by Thread.
In short, the example you've used is a bad one to start with in various ways - but synchronization is used for more than just wait/notify.
Please note that total += i is not an atomic operation in Java. So you have to sync also this construct.
You also have not to sync notify() and wait() because their locks are handled internally.
Expanding on the answer by #sk2212, the increment operation is not atomic, but there is an equivalent atomic operation provided in high-level concurrency primitives.
I know that similar questions have been discussed in this site, but I have not still got further by their aid considering a specific example. I can grasp the difference of notify() and notifyAll() regarding Thread "awakeining" in theory but I cannot perceive how they influence the functionality of program when either of them is used instead of the other. Therefore I set the following code and I would like to know what is the impact of using each one of them. I can say from the start that they give the same output (Sum is printed 3 times).
How do they differ virtually? How could someone modify the program, in order for the applying notify or notifyAll to play a crucial role to its functionality (to give different results)?
Task:
class MyWidget implements Runnable {
private List<Integer> list;
private int sum;
public MyWidget(List<Integer> l) {
list = l;
}
public synchronized int getSum() {
return sum;
}
#Override
public void run() {
synchronized (this) {
int total = 0;
for (Integer i : list)
total += i;
sum = total;
notifyAll();
}
}
}
Thread:
public class MyClient extends Thread {
MyWidget mw;
public MyClient(MyWidget wid) {
mw = wid;
}
public void run() {
synchronized (mw) {
while (mw.getSum() == 0) {
try {
mw.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Sum calculated from Thread "
+ Thread.currentThread().getId() + " : " + mw.getSum());
}
}
public static void main(String[] args) {
Integer[] array = { 4, 6, 3, 8, 6 };
List<Integer> integers = Arrays.asList(array);
MyWidget wid = new MyWidget(integers);
Thread widThread = new Thread(wid);
Thread t1 = new MyClient(wid);
Thread t2 = new MyClient(wid);
Thread t3 = new MyClient(wid);
widThread.start();
t1.start();
t2.start();
t3.start();
}
}
UPDATE:
I write it explicitly. The result is the same whether one uses notify or notifyAll:
Sum calculated from Thread 12 : 27
Sum calculated from Thread 11 : 27
Sum calculated from Thread 10 : 27
Therefore my question: What is the difference?
The difference is subtler than your example aims to provoke. In the words of Josh Bloch (Effective Java 2nd Ed, Item 69):
... there may be cause to use notifyAll in place of notify. Just as placing the wait invocation in a loop protects against accidental or malicious notifications on a publicly accessible object, using notifyAll in place of notify protects against accidental or malicious waits by an unrelated thread. Such waits could otherwise “swallow” a critical notification, leaving its intended recipient waiting indefinitely.
So the idea is that you must consider other pieces of code entering wait on the same monitor you are waiting on, and those other threads swallowing the notification without reacting in the designed way.
Other pitfalls apply as well, which can result in thread starvation, such as that several threads may wait for different conditions, but notify always happens to wake the same thread, and the one whose condition is not satisfied.
Even though not immediately related to your question, I feel it is important to quote this conclusion as well (emphasis by original author):
In summary, using wait and notify directly is like programming in “concurrency assembly language,” as compared to the higher-level language provided by java.util.concurrent. There is seldom, if ever, a reason to use wait and notify in new code. If you maintain code that uses wait and notify, make sure that it always invokes wait from within a while loop using the standard idiom. The notifyAll method should generally be used in preference to notify. If notify is used, great care must be taken to ensure liveness.
This is made clear in all sorts of docs. The difference is that notify() selects (randomly) one thread, waiting for a given lock, and starts it. notifyAll() instead, restarts all threads waiting for the lock.
Best practice suggests that threads always wait in a loop, exited only when the condition on which they are waiting is satisfied. If all threads do that, then you can always use notifyAll(), guaranteeing that every thread whose wait condition has been satisfied, is restarted.
Edited to add hopefully enlightening code:
This program:
import java.util.concurrent.CountDownLatch;
public class NotifyExample {
static final int N_THREADS = 10;
static final char[] lock = new char[0];
static final CountDownLatch latch = new CountDownLatch(N_THREADS);
public static void main(String[] args) {
for (int i = 0; i < N_THREADS; i++) {
final int id = i;
new Thread() {
#Override public void run() {
synchronized (lock) {
System.out.println("waiting: " + id);
latch.countDown();
try { lock.wait(); }
catch (InterruptedException e) {
System.out.println("interrupted: " + id);
}
System.out.println("awake: " + id);
}
}
}.start();
}
try { latch.await(); }
catch (InterruptedException e) {
System.out.println("latch interrupted");
}
synchronized (lock) { lock.notify(); }
}
}
produced this output, in one example run:
waiting: 0
waiting: 4
waiting: 3
waiting: 6
waiting: 2
waiting: 1
waiting: 7
waiting: 5
waiting: 8
waiting: 9
awake: 0
None of the other 9 threads will ever awaken, unless there are further calls to notify.
notify wakes (any) one thread in the wait set, notifyAll wakes all threads in the waiting set. notifyAll should be used most of the time. If you are not sure which to use, then use notifyAll.
In some cases, all waiting threads can take useful action once the wait finishes. An example would be a set of threads waiting for a certain task to finish; once the task has finished, all waiting threads can continue with their business. In such a case you would use notifyAll() to wake up all waiting threads at the same time.
Another case, for example mutually exclusive locking, only one of the waiting threads can do something useful after being notified (in this case acquire the lock). In such a case, you would rather use notify(). Properly implemented, you could use notifyAll() in this situation as well, but you would unnecessarily wake threads that can't do anything anyway.
Javadocs on notify.
Javadocs on notifyAll.
Once only one thread is waiting to sum to not be zero, there is no difference. If there are several threads waiting, notify will wake up only one of them, and all the other will wait forever.
Run this test to better understand the difference:
public class NotifyTest implements Runnable {
#Override
public void run ()
{
synchronized (NotifyTest.class)
{
System.out.println ("Waiting: " + this);
try
{
NotifyTest.class.wait ();
}
catch (InterruptedException ex)
{
return;
}
System.out.println ("Notified: " + this);
}
}
public static void main (String [] args) throws Exception
{
for (int i = 0; i < 10; i++)
new Thread (new NotifyTest ()).start ();
Thread.sleep (1000L); // Let them go into wait ()
System.out.println ("Doing notify ()");
synchronized (NotifyTest.class)
{
NotifyTest.class.notify ();
}
Thread.sleep (1000L); // Let them print their messages
System.out.println ("Doing notifyAll ()");
synchronized (NotifyTest.class)
{
NotifyTest.class.notifyAll ();
}
}
}
I found what is going on with my program. The three Threads print the result even with the notify(), because they do not manage to enter the waiting state. The calculation in the widThread is performed quickly enough to preempt the entering of the other Threads in the waiting state, since it depends on the condition mw.getSum() == 0 (while loop). The widThread calculates the sum, so that the remaining Threads do not ever "see" its value as 0.
If the while loop is removed and the start of widThread comes after the start of the other Threads, then by notify() only one Thread prints the result and the others are waiting forever, as the theory and the other answers indicate.
I know that there are a few threads open regarding this topic, but I'm just looking for a VERY ELEMENTARY example of how to use wait() and notify() in Java. By "VERY ELEMENTARY," I mean simply printing something out. Thanks.
EDIT: Here's what I have tried thus far and I get an IllegalMonitorStateException:
public void waiting() {
for(int i = 0; i < 10; i++) {
if(i == 5)
try {
this.wait();
} catch (InterruptedException e) {
}
else
System.out.println(i);
}
System.out.println("notify me now");
this.notify();
}
wait and notify are used in synchronized block while using threads to suspend and resume where left off.
Wait immediately looses the lock, whereas Nofity will leave the lock only when the ending bracket is encountered.
public class Mythread implements Runnable{
public synchronized void goo(){
System.out.println("Before Wait");
wait();
System.out.println("After Wait");
}
public synchronized void foo(){
System.out.println("Before Notify");
notify();
System.out.println("After Notify");
}
public class Test{
public static void main(String[] args){
Thread t = new Thread(new Mythread);
t.start();
}
}
Your IllegalMonitorStateException is due to the fact that you must synchronize on the object before calling wait or notify. So
this.wait
needs to be
synchronized(this) {
this.wait();
}
Your example won't run because you'll never get to the notify call... as soon as your thread hits wait, it will suspend and advance no further. For wait / notify to work, you have to have two threads. One thread suspends when the wait method is invoked, and eventually, the second thread calls synchronized(this) { this.notify() } to cause the first thread to wake up and continue executing below the wait call.
The synchronization is required because you would ordinarily check some condition before waiting, ie,
synchronized(this) {
if(! this.isReady) {
this.wait();
}
}
You need to synchronize to make sure no other thread changes the state of the isReady flag between the line where you check the variable and the line where you wait. So your notify code would
synchronized(this) {
isReady = true;
this.notify();
}
Now the order of the method calls doesn't matter. If you notify first, no thread will wake up, but that's ok, because you aren't going to sleep since isReady = true. If you go to sleep first, isReady = true does nothing, but the notify call wakes up the thread. Finally, the synchronization ensures that you don't check the variable in thread A, then have thread B set the variable and notify (doing nothing), then have thread A go to sleep and never wake up.
Hope that helps.
wait() and notify() are used to synchronise threads: a thread can be told to wait(), and will not continue doing anything until it receives the notify() call.
The basic idea with these functions is that wait() suspends a thread (puts it to sleep), and notify() causes a thread to pick up where it left when it went to sleep.
Take a look at: this or just look up simple prodcuer consumer problem java on google. I am sure you will find something to suit your needs.
See this example on guarded blocks from the oracle java site - it includes a worked example of a simple producer-consumer problem.
So I have the following code:
import java.lang.Thread;
import java.lang.Integer;
class MyThread extends Thread {
private int id;
MyThread(int i){
id = i;
}
public void run() {
while(true){
try{
synchronized(Global.lock){
Global.lock.wait();
if(Global.n == 0) {System.out.println(id); Global.lock.notify(); break;}
--Global.n;
System.out.println("I am thread " + id + "\tn is now " + Global.n);
Global.lock.notify();
}
}
catch(Exception e){break;}
}
}
}
class Global{
public static int n;
public static Object lock = new Object();
}
public class Sync2{
public static final void main(String[] sArgs){
int threadNum = Integer.parseInt(sArgs[0]);
Global.n = Integer.parseInt(sArgs[1]);
MyThread[] threads = new MyThread[threadNum];
for(int i = 0; i < threadNum; ++i){
threads[i] = new MyThread(i);
threads[i].start();
}
synchronized(Global.lock){Global.lock.notify();}
}
}
two parameters are entered: a number n and the number of threads to be created. Every thread decreases n by one and then passes control. All threads should stop when n is 0. It seems to work fine so far, but the only problem is that in most of the cases all threads except one terminate. And one is hanging on. Any idea why?
And yes, this is part of a homework, and that is what I've done so far (I was no provided with the code). I'am also explicitly restricted to use a synchronized block and only wait() and .notify() methods by the task.
EDIT: modified the synchronized block a bit:
synchronized(Global.lock){
Global.lock.notify();
if (Global.n == 0) {break;}
if (Global.next != id) {Global.lock.wait(); continue;}
--Global.n;
System.out.println("I am thread " + id + "\tn is now " + Global.n);
Global.next = ++Global.next % Global.threadNum;
}
now threads act strictly in the order they are created. Its pretty unclear from the task wording, but might be the right thing.
You have a race condition. Think about what happens with a single worker thread. Global.n is set to 1 and then the thread starts. It immediately goes into a wait state. Suppose, though, that notify() had already been called on the main thread. Since the worker thread hasn't yet entered a wait state, it isn't notified. Then, when it finally does call wait(), there are no other threads around to call notify(), it stays in the wait state forever. You need to fix up your logic to avoid this race condition.
Also, do you really want a single worker thread to decrement Global.n more than once? That can easily happen with your while (true) ... loop.
EDIT
You also have another logic problem with a single thread. Suppose it enters the wait state and then the notify() in main is called. It wakes the worker thread which decrements Global.n to 0, calls notify(), and then goes back to waiting. The problem is that notify() didn't wake any other thread because there were no other threads to wake. So the one worker thread will wait forever. I haven't analyzed it fully, but something like this might also happen with more than one worker thread.
You should never have a naked wait() call, as semaphores in java are not cached. wait() should always be nested in some sort of
while (condition that you are waiting on)
obj.wait();