Please see the below code, where the notifyAll is commented. Still the main thread is printing the total? How is it possible?
public 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){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}}
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
// notify();
}
}
}
What you see is the result of something documented in the javadoc of Thread.join():
As a thread terminates the this.notifyAll method is invoked.
Note that it goes on with
It is recommended that applications not use wait, notify, or notifyAll on Thread instances
Also note that a thread blocked on wait() can go out of its waiting state without any notification, due to spurious wakeups. And the javadoc of wait() clearly explains that wait() should always be called inside a loop.
Also note: The Java API doc for Object.wait() says, "...interrupts and spurious wakeups are possible, and this method should always be used in a loop."
That is generally true in other APIs and other languages as well. A method/function should never assume that the condition it was waiting for is true just because a wait() operation on a condition variable returned. There should always be a loop. In pseudo-code:
lock mutex
while (! ok_to_do_whatever()) {
wait on condition_variable
}
do_whatever()
unlock mutex
Try this and the waiting thread will wait forever...
public class ThreadA {
public static Object lock = new Object();
public static void main(String[] args){
ThreadB b = new ThreadB();
b.start();
synchronized(lock){
try{
System.out.println("Waiting for b to complete...");
lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread
{
int total;
#Override
public void run(){
synchronized(ThreadA.lock){
for(int i=0; i<100 ; i++){
total += i;
}
// notify();
}
}
}
Related
I have written a program which creates a 2 new thread and shares a common lock object to print numbers alternatively.
Wanted to know if the approach for using wait() and notify() is correct?
Main Class
public class MyMain {
public static void main(String[] args) {
MyThread1 obj = new MyThread1();
Thread thread1 = new Thread(obj);
Thread thread2 = new Thread(obj);
thread1.setName("t1");
thread2.setName("t2");
thread1.start();
thread2.start();
}
}
Thread Class
public class MyThread1 implements Runnable{
int i = 0;
#Override
public synchronized void run() {
while(i<10)
{
if(i%2==0)
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}else
{
try{
notify();
System.out.println(Thread.currentThread().getName()+" prints "+i);
i++;
wait();
}catch(Exception e){ e.printStackTrace(); }
}
}
}
}
Can there be a better usage of wait() and notify() instead of using it in both the if conditions?
Since there you have some code repetition I'd just go with something like:
while(true) {
//If it's not my turn I'll wait.
if(i%2==0) wait();
// If I've reached this point is because:
// 1 it was my turn OR 2 someone waked me up (because it's my turn)
System.out.println(Thread.currentThread()": "+i);
i++; // Now is the other thread's turn
// So we wake him up
notify();
}
Also, be very careful with monitor's behaviour. (Thread waiting/notifying queues).
I am reading some code in OCA/OCP Java SE 7 Programmer I & II Study Guide, and I got stuck on an example:
package threads;
class Totalizer implements Runnable
{
int total = 0;
public void run(){
synchronized(this){
for(int i = 0; i < 100; i++){
total += i;
}
notifyAll();
}
}
}
class Tester extends Thread
{
Totalizer t;
public Tester(Totalizer tot){t = tot;}
public void run(){
synchronized(t){
try {
System.out.println("Waiting for calculation...");
t.wait();
} catch (InterruptedException e) {}
System.out.println(t.total);
}
}
public static void main(String[] args){
Totalizer t = new Totalizer();
new Tester(t).start();
new Tester(t).start();
new Tester(t).start();
}
}
//
When I run main(), it prints:
waiting for calculation...
waiting for calculation...
waiting for calculation...
and nothing happens, no calculation, nothing. I can't figure out what is wrong with this code.
Two points.
The most obvious one is that you never start the Totalizer runnable, so the notifyAll call is never issued. You need to have a line
new Thread(t).start();
somewhere in your main method. But even if you do that, it won't work reliably, as the wait call may be invoked after the notifyAll call. It may also print the output too early, as the wait call can wake up without a notifyAll as well.
The Javadoc for Object.wait() describes what you need to do:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
So, you can't just call Object.wait just like that, if you want to use it correctly. This is because:
You don't know if the condition was already satisfied earlier, before you started waiting
The wait call may also wake up without a notify call
In your case, you need a condition variable that you can check. For example, you can change your code like this:
class Totalizer implements Runnable
{
int total = 0;
boolean calculationComplete; // Condition to check in wait()
public void run() {
for(int i = 0; i < 100; i++) {
total += i;
}
synchronized (this) {
// Indicate condition for wait() is now true
calculationComplete = true;
notifyAll();
}
}
}
class Tester extends Thread
{
Totalizer t;
public Tester(Totalizer tot){t = tot;}
public void run(){
synchronized(t) {
System.out.println("Waiting for calculation...");
// Loop, terminate when condition is true
while (!t.calculationComplete) {
try {
t.wait();
} catch (InterruptedException e) {}
}
System.out.println(t.total);
}
}
Why doesn't thread wait for notify()? The thread starts and then goes to the waiting pool, but it proceeds to execute after that moment.
public class JavaApplication2 {
public static void main(String [] args) {
ThreadB b = new ThreadB();
synchronized(b) {
b.start();
try {
System.out.println("1");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
synchronized(this) {
total += 1;
//notify();
}
}
}
You are synchronizing on the thread object itself, which is wrong usage. What happens is that the dying thread-of-execution always calls notify on its Thread object: Thread.join relies on this. Therefore it is clear why you get the same behavior with and without your own notify in there.
Solution: use a separate object for thread coordination; this is the standard practice.
The method notifyAll() is invoked for the Thread object of the terminating thread. This fact is strangely documented in the description of the Thread.join, with the following sentence:
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Thus, if you don't explicitly read the description of join, which you don't necessarily have to, you don't get to know the reason for the strange behavior.
You cannot depend on not returning from wait until a notify: "interrupts and spurious wakeups are possible". In general, you should wrap a wait call in a loop while the thread should go on waiting.
If you try your code synchronizing on any object other that ThreadB you will find it never terminates. This is because there is a hidden call to notify.
Although I am not aware of anywhere that this is specified, Thread notifies itself when it ends. This is implicit in the way the join method is implemented. This is the code for join:
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;
}
}
}
(From the JDK7 source code)
As you can see, the calls to wait only make sense if somewhere there is a call to notify that is called after the thread ends. The same call to notify is what allows your program to terminate.
You have nested synchronized {} constructs in the two places. These constructs seem doing something weird: the thread does not react into notify at all and only resumes when ThreadB (b) terminates. Remove this:
public class JavaApplication2 {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println(" ### Waiting for notify");
synchronized (b) {
b.wait();
}
System.out.println(" ### Notified");
} catch (InterruptedException e) {
}
System.out.println("### Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
total += 1;
System.out.println(" *** Ready to notify in 5 secs");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** Notification sent");
synchronized (this) {
notify();
}
System.out.println(" *** 5 sec post notification");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** ThreadB exits");
}
}
The code above probably works correctly: with notify() present the main thread resumes after 5 seconds and before we see the message that ThreadB terminates. With notify() commented out the main thread resumes after 10 seconds and after the message about the termination of the ThreadB because notify() is called anywhay from the other code. Marko Topolnik explains why and from where this "behind the scene" notify() call comes from.
I was doing the same testing on the wait/notify opertaions while reading OCP SE 7, good catch. I think we should let the authoer to explain.
I have developed a program in which the thread A waits for Thread B to complete it task and when thread B finishes its task it makes notfiy() to thread A to continue onwards..below is the code..
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.totals);
}
}
}
class ThreadB extends Thread {
public int totals;
public void run() {
synchronized(this) { //instance level lock
for(int i=0;i<100;i++) {
totals += i;
}
notify();
}
}
}
Now I want lets say 3 more thread are waiting for thread b , so please advise me how to spawn 3 more threads , just like thread A is waiting , please advise.
Use the ExecutorService it has a methode invokeAll(). You can submit all your ThreadB and hold a List of Future's.
Your current code actually contain possible deadlock since you start() the threadB first and it is calling the notify() in its run(). This notify() is possible to be called before the wait() in the main. If this happens, you threadB will be waiting forever.
To start more ThreadB, you just need to create more instances.
ThreadB threadBs = new ThreadB[3];
for (ThreadB b : threadBs) {
b = new ThreadB();
b.start();
}
However, I will suggest implementing the Runnable interface instead of just extending the Thread class.
I'm reading through my SCJP book and I'm on the chapter about threads, and I am wondering why you should use notify at all.
Here is my sample program using notify:
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 < 100000000; i++){
total++;
}
notify();
}
for(int i = 0; i < 100000000; i++){
total++;
}
}
}
If I take out the notify call, it still executes in the same way. I.E., once the lock is released, the b.wait() stops blocking eventually and we get a semi random number between 100000000 and 200000000, depending on the scheduler.
This code:
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 < 100000000; i++){
total++;
}
notify();
}
}
}
Always results in 100000000 getting printed regardless wither the notify is there or not.
And this code:
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 < 100000000; i++){
total++;
}
notify();
for(int i = 0; i < 100000000; i++){
total++;
}
}
}
}
Always prints out 200000000 regardless of the notify being present or absent.
So as far as I can tell, the only thing the notify does is possibly waking up a thread earlier than needed, if that is the case, why use notify at all? Why not wait for the lock to be released and let the JVM restart the other thread?
Unless you or someone else calls notify(), the wait() should continue forever, barring spurious wakes. Are you sure nothing's interrupting the thread?
Basically you use notify() precisely to wake up threads. If you don't need to put a thread to sleep until another thread can notify it that it should wake up, don't use it.
EDIT: Okay, I've reproduced this behaviour - and I suspect it's because you're calling wait() on the thread object itself. My guess is that the Thread object gets notified when the thread terminates.
Try waiting on a shared plain Object, like this:
class ThreadA {
static Object monitor = new Object();
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(monitor) {
try {
System.out.println("Waiting for b to complete...");
monitor.wait();
}catch(InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
public void run() {
synchronized(ThreadA.monitor) {
for (int i = 0; i < 100000000; i++) {
total++;
}
// ThreadA.monitor.notify();
}
}
}
If you uncomment that line, the program terminates - otherwise it doesn't.
EDIT: I've actually found some documentation on this. From Thread.join(millis, nanos):
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.