Need to clear my mind on methods wait() e notify(); - java

class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet)
try {
wait();
} catch (Exception e) {
}
;
System.out.println("Pego : " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet)
try {
wait();
} catch (Exception e) {
}
;
this.n = n;
valueSet = true;
System.out.println("Inserido : " + n);
notify();
}
}
class Producer2 implements Runnable {
Q q;
Producer2(Q q) {
this.q = q;
new Thread(this, "Geradora").start();
}
public void run() {
int i = 0;
while (true) {
q.put(i++);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer2 implements Runnable {
Q q;
Consumer2(Q q) {
this.q = q;
new Thread(this, "Consumidora").start();
}
public void run() {
while (true) {
q.get();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class PCFixed {
public static void main(String[] args) {
Q q = new Q();
new Producer2(q);
new Consumer2(q);
}
}
Text from the book:
Inside get(), wait() is called. This suspends the execution till Producer notify...
My question is, Once I instantiate Producer and Consumer, the execution reaches put, not get. So how come it calls get first and then call wait() inside get()?

The system can only be in one of two states:
It is empty
valueSet is false, the put method will not even once enter that while loop and thus never invokes wait(), and the get method would wait().
It is full
valueSet is true, the get method will not even once enter that while loop and thus never invokes wait(), and the put method would wait().
Explanation
Because the get and put methods are synchronized, only one can be running (and note that wait() will open the gates and let other code run. It'll re-acquire the lock before wait() actually exits - for code to go on past a wait(), both notify() must be called, and whatever called it needs to get to the end of it synchronized block/method.
The code starts off in 'empty' mode.
It doesn't matter if you attempt to invoke put and get simultaneously; these methods are synchronized on the this reference so only one can actually run, the other would freeze until the lock is available. Thus, we have two options:
The put call wins. In this case, the put call will immediately set the value and not wait at all, sets the mode to 'full' (valueSet = true), does a useless notify() that has no effect but also does no harm, and ends. The get call was waiting to start and can now start. It will not wait at all (as it is in "full" mode; valueSet == true), gets the value and prints it, sets the mode back to empty, does another useless notify, and exits.
The get call wins. In this case, the get call will enter the while loop and waits. This releases the lock, which means the put call can now go. It will not wait at all (as the while loop's condition is false, which means it runs zero times), it sets a value, and notify() - that 'releases' the get() call which now merely waits for the lock to be available to continue. The put method ends, thus releasing the lock. The get call continues and fetches the value. It then does a useless notify, and exits as well.
Instead you attempt to run 2 put calls simultaneously. One wins and immediately sets as usual, then the other runs and will immediately enter wait mode and will be stuck there (as will any further put calls, they all run into the wait() call and wait there), until you call get() in some thread, this will get a value, set the thing to be in 'empty' mode, and notifies one arbitrary thread, thus unlocking it. It will put its value and set your object back to "full" mode and exit, leaving the other putters still waiting around. Another get call would immediately proceed, fetch it, notify another one of the waiting put calls, and so on.

Because both Producer2 and Consumer2 create a new thread in their constructors.
So calling
new Producer2(q);
In the main method, doesn't stop the execution, it goes immediately to the next line which is
new Consumer2(q);
Which is where the call to q.get happens

Related

Can a java thread waiting with wait() ,notify itself?

I came across the following e example to implement custom suspend and wait from some website.
// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for (int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
...................
I am more concerned about the ob1.mysuspend() and ob1.myresume() calls. When my suspend is called then ob1 will be placed into the blocking queue associated with the runnable object it is using. When ob1 calls myresume, then how does it work as ob1 is already in waiting queue for the same object, can the waiting object enters another synchronised method and then signals notify to itself?How does this work?What am I missing?
The thread is written so that while an instance of NewThread is running, another thread can call mysuspend to suspend that running thread. Again, a thread other than the suspended thread calls myresume to resume the suspended thread.
There also appears to be a data race because mysuspend writes to suspendFlag without any synchronization. That means, the thread that needs to be suspended may not see that write immediately. mysuspend must be declared synchronized, or suspendFlag must be volatile.
This code is flat out broken.
Straight up broken: JMM violation
The mysuspend method (which should be named mySuspend, by the way) updates a field that is then read from another thread, and isn't synchronized. This is an error - and a really nasty one because you cannot reliably test that it is an error. The Java Memory Model (JMM) states that any write to a field may be observable or not, at the discretion of the JVM implementation, unless a so-called Happens-Before/Happens-After relationship is established (there are many ways to do it; usually you do so via synchronized, volatile, or some other concurrency tool built on these primitives, such as the latches and queues in the java.util.concurrent package).
You do not establish such a relationship here, meaning, that suspendFlag = true results in a schroedingers cat variable: The other thread that reads this field may read true or false, the JVM gets to decide what you see. Hence: A bug, and, untestable. bad. Any field that is read/written to by multiple threads needs to be written extremely carefully.
Mark that method synchronized, that's a good first step.
Wait and Notify
You've got it flipped around: You must in fact hold the synchronized lock on x when you invoke wait on x (here, x is this).
To call x.wait() (you are calling this.wait(), effectively), you must first be in a synchronized(x) block. Once the wait 'goes through', the code releases the lock (other synchronized(x) blocks can run). To invoke x.notify() you must also hold that lock.
wait does not return until the lock is re-established.
In other words:
public void foo() {
wait();
}
will fail at runtime. Try it. Guaranteed exception. In the mean time, this:
public void foo() {
synchronized (this) {
// code before wait
wait();
// code after wait
}
}
is executed as if it is written like this:
public void foo() {
synchronized (this) {
// code before wait
release_lock(this);
this.wait();
acquire_lock(this);
// code after wait
}
}
Where acquire_lock is guaranteed to actually take a while (because by definition whatever invoked notify() to wake you up is currently holding it! So wait is always a two-hit thing: You need to be both notified AND the lock needs to be reacquired before your code will continue). Except, of course, acquire_lock and release_lock don't exist, and unlike this hypothetical code, wait() is more atomic than that.

Consumer thread does not get notified [duplicate]

I have a thread that calls the wait method and can only be awoken when the notify method called from some other class:
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);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i=0;i<100;i++) {
total += i;
}
notify();
}
}
}
In the above code if the synchronized block in main, if the ThreadA does not execute first and instead the other synchronization block executing and completes to completion, then ThreadA executes its synchronized block and calls wait, what is going to happen and how it will be notified again?
If ThreadB gets through its synchronized block before ThreadA does, then ThreadA will block indefinitely on the call to wait. It won't somehow be notified that the other thread has already completed.
The problem is that you're trying to use wait and notify in ways that they are not designed to be used. Usually, wait and notify are used to have one thread wait until some condition is true, and then to have another thread signal that the condition may have become true. For example, they're often used as follows:
/* Producer */
synchronized (obj) {
/* Make resource available. */
obj.notify();
}
/* Consumer */
synchronized (obj) {
while (/* resource not available */)
obj.wait();
/* Consume the resource. */
}
The reason that the above code works is that it doesn't matter which thread runs first. If the producer thread creates a resource and no one is waiting on obj, then when the consumer runs it will enter the while loop, notice that the resource has been produced, and then skip the call to wait. It can then consume the resource. If, on the other hand, the consumer runs first, it will notice in the while loop that the resource is not yet available and will wait for some other object to notify it. The other thread can then run, produce the resource, and notify the consumer thread that the resource is available. Once the original thread is awoken, it will notice that the condition of the loop is no longer true and will consume the resource.
More generally, Java suggests that you always call wait in a loop because of spurious notifications in which a thread can wake up from a call to wait without ever being notified of anything. Using the above pattern can prevent this.
In your particular instance, if you want to ensure that ThreadB has finished running before ThreadA executes, you may want to use Thread.join(), which explicitly blocks the calling thread until some other thread executes. More generally, you may want to look into some of the other synchronization primitives provided by Java, as they often are much easier to use than wait and notify.
You could loop and wait until the total has been computed :
synchronized(b) {
while (total == 0) {
b.wait();
}
}
You could also use a higher-level abstraction like a CountDownLatch.
It is possible for ThreadB's run method to complete before you enter the synchronized block in ThreadA.main. In that situation, since the notify call has happened before you started waiting, ThreadA will block forever on the wait call.
A simple workaround would be to grab the lock on b in main before you start the second thread to ensure the wait happens first.
ThreadB b = new ThreadB();
synchronized(b) {
b.start();
...
b.wait();
}
You probably want to use a java.util.concurrent.Semaphore for this.
1) You need to add some flag that is used to communicate between the threads, so that B can signal to A when it is finished. A simple boolean variable is fine, as long as it is only read and written within the synchronized blocks.
synchronized(this) {
for(int i=0;i<100;i++) {
total += i;
}
isDone = true;
notify();
}
2) A needs to loop while waiting. So if your boolean variable was called isDone, and was set to true by threadB, then threadA should have some code like this:
synchronized(b) {
System.out.println("Waiting for b to complete...");
while( ! isDone ) b.wait();
}
In this particular case, there's actually no reason to have the synchronized block in A - since threadB doesn't do anything after it finishes running, and A doesn't do anything except wait for B, threadA could simply call b.join() to block until it finishes. I assume that your actual use case is more complex than this.
Why to make that complex ? Just use join() function of Thread.
ThreadB b = new ThreadB();
b.start();
b.join();
// now print b.total
do not synchronized(thread), don't do it, do not synchronized(thread).. repat: no synchronized(thread) :)
And if you need to wait for the thread 'b' to finish, use b.join(), now your code is free to hang in b.wait()
--
Hopefully the source below can grant you an insight while sync(thread)/notify() I consider bad practice. (cut-cut)
Enjoy
To proceeed below you make sure you have accepted Oracle's License aggreement, found there:
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewLicense-Start?LicenseUUID=7HeJ_hCwhb4AAAEtmC8ADqmR&ProductUUID=pGqJ_hCwj_AAAAEtB8oADqmS&cnum=&evsref=&sln=
Java sources (incl), called in init(), effectively called by any java c-tor, since java 1.5
private static **synchronized int** nextThreadNum() {
return threadInitNumber++;
}
//join (the method w/ nanos only increase millis by one, if nanos>500000, millis==0 and nanos>0
public final **synchronized** void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
public **synchronized** void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
//stop1 is called after stop ensures proper priviledges
private final **synchronized** void stop1(Throwable th) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if ((this != Thread.currentThread()) ||
(!(th instanceof ThreadDeath))) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status value corresponds to "NEW"
if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise
stop0(th);
} else {
// Must do the null arg check that the VM would do with stop0
if (th == null) {
throw new NullPointerException();
}
// Remember this stop attempt for if/when start is used
stopBeforeStart = true;
throwableFromStop = th;
}
}

Java Threading Cyclic Notify() and Wait()

I'm having a code in Java where two objects wait and notify each other when one finished processing. I'll keep my code simple with the following example and assuming there are no syntax error (I just want you to know the logic is more important here rather than the syntax).
Assuming I have object A which is a thread having this pseudo code
class A is Thread {
run() {
while(true) {
wait(); // wait for signal from B
// then do something if signal received
B.signal(); // let B know that we're done and wait again
}
}
}
Then we have here B which is also a thread having this pseudo code
class B is Thread {
run() {
while(true) {
// Do something
A.signal(); // Let A know to continue processing
wait(); // Wait for signal from A before doing something again
}
}
}
So as you can see there's a cycle. The problem is I am having a dead-lock and the reason here is because when A is finished processing, it signals B to work before it waits.. But by the time B is notified, there are chances that A still haven't reached the wait() code and B is already calling A.signal() and leads to a dead lock.
How do I properly solve this problem? The solution I have in mind is that when B is notified to work, I will let the thread of B sleep for a number of milliseconds but I don't think this is ever a good idea. Any help is appreciated, thanks in advance.
When you use notify() this should be associated with a state change.
When you use wait() this should be associated with a check for a state change.
In real code, you should only wait when you are waiting for something.
Note: wait() can wake spuriously, it doesn't mean notify() was called. As you noticed, notify() does nothing if nothing is wait()ing.
Instead of using this pattern, you can use a BlockingQueue to pass work/messages between threads. This has the wait/notify and the object containing work built in.
However, since you normally need a thread to do the work, there is an ExecutorService builtin to do this. This allows you to pass work to a pool of threads and collect the results.
In short, you should be using an ExecutorService.
If A is using the result of B, then maybe you can consider a BlockingQueue.
As you can find described in the Javadoc, you need to put your wait calls inside a loop that checks for a condition. Otherwise, if you don't have a condition variable or expression that you can check, it is possible that you miss the notify because you were not waiting at that point.
Also, as others have pointed out, you need to hold the monitor of the object you are calling the wait or notify method on; that's what the synchronized keyword is for.
In the below fix, the condition is very simple; it's a variable called notified in classes A and B.
Also, to get this right, A and B need to know about each other. In your code you seemed to be invoking static methods; but the notify method needs to be called on an instance, so you need to keep references to the instances of A and B in B and A, respectively.
This fixes the problems:
class A is Thread {
private B b;
private boolean notified;
public void run() {
while(true) {
synchronized(this) {
while (!notified) {
try {
wait(); // wait for signal from B
} catch (InterruptedException e) {}
}
notified = false;
}
synchronized(b) {
// then do something if signal received
b.notified = true;
b.notify(); // let B know that we're done and wait again
}
}
}
}
class B is Thread {
private A a;
private boolean notified;
public void run() {
while(true) {
synchronized(a) {
// Do something
a.notified = true;
a.notify(); // Let A know to continue processing
}
synchronized(this) {
while (!notified) {
try {
wait(); // Wait for signal from A before doing something again
} catch (InterruptedException e) {}
}
notified = false;
}
}
}
}

Java synchronization wait and notify methods

I'm a newbie to synchronization and trying to understand how wait and notify works.
Question:-
The programs executes 2 threads - T1 & T2 simultaneously but based on the output T1 runs first, executes the question(first) method, prints the question, sets the flag(true), runs the notify() method, executes the question(second) method & enters the wait method. Now T2 starts and executes.
Why does T2 doesn't start until T1 calls the wait method of the Object Chat.
When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). so, which thread listens to this notify method.
My codes:
package TestThread;
class Chat {
boolean flag = false;
public synchronized void Question(String msg) {
System.out.println("Question method = " + flag);
if (flag) {
try {
System.out.println("Question method wait start");
wait();
System.out.println("Question method wait finish");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = true;
notify();
}
public synchronized void Answer(String msg) {
System.out.println("Answer method = " + flag);
if (!flag) {
try {
System.out.println("Answer method wait start");
wait();
System.out.println("Answer method wait finish");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = false;
notify();
}
}
class T1 implements Runnable {
Chat m;
String[] s1 = { "Hi", "How are you ?", "I am also doing fine!" };
public T1(Chat m1) {
this.m = m1;
new Thread(this, "Question").start();
}
public void run() {
for (int i = 0; i < s1.length; i++) {
m.Question(s1[i]);
}
}
}
class T2 implements Runnable {
Chat m;
String[] s2 = { "Hi", "I am good, what about you?", "Great!" };
public T2(Chat m2) {
this.m = m2;
new Thread(this, "Answer").start();
}
public void run() {
for (int i = 0; i < s2.length; i++) {
m.Answer(s2[i]);
}
}
}
public class MultiThread {
public static void main(String[] args) {
Chat m = new Chat();
new T1(m);
new T2(m);
}
}
Result:-
Question method = false
Hi
Question method = true
Question method wait start
Answer method = true
Hi
Answer method = false
Answer method wait start
Question method wait finish
How are you ?
Question method = true
Question method wait start
Answer method wait finish
I am good, what about you?
Answer method = false
Answer method wait start
Question method wait finish
I am also doing fine!
Answer method wait finish
Great!
Why does T2 doesn't start until T1 calls the wait method of the Object
Chat.
You have a same object 'm' and passed it to different threads and there is method level synchronization , so the moment a 'call' enters the question() there will be lock on whole object till wait() is called Hence answer method will be blocked.
When the question method is executed first time and notify() method is
called, there is no wait() on the chat object(since t2 did not yet
start). so, which thread listens to this notify method.
notify() has no significance for the first time, synchronized method has to finish thats all. as said earlier answer() is not executed till the question() finishes / releases the lock (calling wait())
Why does T2 doesn't start until T1 calls the wait method of the Object Chat?
You've got a race condition. Either of the two threads will execute first. Since they both share a single Chat instance, whose methods are synchronized, one will block until the other has unlocked the monitor on the Chat instance.
When the question method is executed first time and notify() method is
called, there is no wait() on the chat object(since t2 did not yet
start). so, which thread listens to this notify method?
None do.
1.) Why does T2 doesn't start until T1 calls the wait method of the Object Chat?
Actually T2 starts before that but you don't notice because you don't have any logging statements to show up. Put a System.out inside run method of T2 and run your program a few times. You will see T2 starting before T1 calls wait method. Keep in mind T2 cannot enter the Chat object's Answer method since its lock is acquired by T1 before wait() is eventually called.
Another thing to keep in mind is that there is no guarantee of the order in which threads will be started. Just because T1.start appears before T2.start , does not mean T1 will always be started first. Thread scheduler makes that decision.
2.)When the question method is executed first time and notify() method is called, there is no wait() on the chat object(since t2 did not yet start). so, which thread listens to this notify method.
--If there has been no wait calls , then notify won't impact any threads.

How will notifyAll work in this scenario?

Here is the small snippet of multi-threaded queue I wrote,
synchronized void add(int i) {
if (count == size) {
System.out.println("******full***");
isQueueFull = true;
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("adding number: " + i);
val[end++] = i;
count++;
if (isQueueEmpty) {
isQueueEmpty = false;
this.notifyAll();
}
}
synchronized int remove() {
if (count == 0) {
isQueueEmpty = true;
System.out.println("******empty***");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int t = val[0];
for (int i = 0; i < end - 1; i++) {
val[i] = val[i + 1];
}
val[end - 1] = -1;
end--;
count--;
if (isQueueFull) {
isQueueFull = false;
this.notifyAll();
}
System.out.println("removing number: " + t);
return t;
}
Lets say I have four threads adding to the queue and one thread removing from the queue. At one point,say array get full and I call wait on all four threads adding to the queue.
Now when an element gets removed, I need to call notifyAll on all of the sleeping threads.(It is giving me an arrayOutofBound exception) My questions is this, what is the flow of threads like in case of notifyAll.
Since add is synchronized method, there can only be one thread execution in it. But because of wait, we have now four threading sleeping inside it. So on notifyAll, will all four threads still be inside the add method(despite it being a synchronized method) and execute? or will it done one by one sequentially, with all of the threads being locked until one thread is completed.
It is very difficult for me to debug it in eclipse. I have a work around for arrayOutOfBoundException by putting a return statement after wait, but I would still like to understand the flow in case of notifyAll?
Waiting is very different from sleeping. The javadoc of wait() explains it:
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.
(emphasis mine)
BTW, it also contains a strong rule that you're not respecting:
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
So, when notifyAll() is called, the 4 threads compete to get back the monitor. Each one gets it back once the previous one has released it, and continues executing.

Categories

Resources