When you call notify method on the object, it wakes one of thread waiting for that object. So if multiple threads are waiting for an object, it will wake of one of them. Now you must be wondering which one it will wake up. It actually depends on OS implementation.
notifyAll() :
notifyAll will wake up all threads waiting on that object unlike notify which wakes up only one of them.Which one will wake up first depends on thread priority and OS implementation.
Lets understand it with the help of example:
1. Create a class named File.java:
It is java bean class on which thread will act and call wait and notify method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package org.arpit.java2blog.thread;
public class File {
String name;
boolean isCompleted;
public File(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isCompleted() {
return isCompleted;
}
public void setCompleted(boolean isCompleted) {
this.isCompleted = isCompleted;
}
}
|
2. Create a class named FileReader.java
This thread will wait until other thread call notify method, then after it will complete its processing. It will first take a lock on file object and will be called from synchronized block .So in this example, it will wait for FileWriter to complete the file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package org.arpit.java2blog.thread;
public class FileReader implements Runnable{
File file;
public FileReader(File file) {
super();
this.file = file;
}
@Override
public void run() {
synchronized (file) {
System.out.println(Thread.currentThread().getName()+" is waiting for the file to be completed: "+file.getName());
try {
file.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+": File has been completed now!! you can read it");
}
}
}
|
3. Create a class named FileWriter.java
This class will notify thread(in case of notify) which is waiting on file object. It will not give away lock as soon as notify is called, it first complete its synchronized block. So in this example, FileWriter will complete the file and notify it to FileReaders.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package org.arpit.java2blog.thread;
public class FileWriter implements Runnable{
File file;
public FileWriter(File file) {
super();
this.file = file;
}
@Override
public void run() {
synchronized (file) {
System.out.println("Write is going to start writing the file : " +file.getName() );
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
file.setCompleted(true);
System.out.println("File has been completed now");
file.notify();
System.out.println("notify one reader");
}
}
}
|
4. Create a class NotifyAndNotifyAllMain,java.
This is our main class which will create object of above classes and run it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package org.arpit.java2blog.thread;
public class NotifyAndNotifyAllMain {
public static void main(String args[])
{
// File object on which wait and notify method will be called
File file=new File("Excel file");
FileReader reader1=new FileReader(file);
FileReader reader2=new FileReader(file);
// FileReader threads which will wait for completion of file
Thread thread1=new Thread(reader1,"Reader 1");
Thread thread2=new Thread(reader2,"Reader 2");
thread2.start();
thread1.start();
// To ensure both readers started waiting for the file
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// FileWriter thread which will notify once file get completed
FileWriter fileWriter=new FileWriter(file);
Thread fileWriterThread=new Thread(fileWriter);
fileWriterThread.start();
}
}
|
In case of notify():
When you run above program, you will get following outputs:
|
Reader 2 is waiting for the file to be completed: Excel file
Reader 1 is waiting for the file to be completed: Excel file
Write is going to start writing the file : Excel file
File has been completed now
notify one reader
Reader 2: File has been completed now!! you can read it
|
So here,two FileReader threads(reader 1 and reader 2) are waiting for file to be completed,so they called file.wait(). Once FileWriter completes it’s file, it called file.notify() and reader 2 thread gets up and completes its processing.
In case of notifyAll() :
Lets change FileWriter class to call file.notifyAll().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package org.arpit.java2blog.thread;
public class FileWriter implements Runnable{
File file;
public FileWriter(File file) {
super();
this.file = file;
}
@Override
public void run() {
synchronized (file) {
System.out.println("Write is going to start writing the file : " +file.getName() );
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
file.setCompleted(true);
System.out.println("File has been completed now");
file.notifyAll();
System.out.println("notify all readers");
}
}
}
|
When you run above program, you will get following output:
|
Reader 2 is waiting for the file to be completed: Excel file
Reader 1 is waiting for the file to be completed: Excel file
Write is going to start writing the file : Excel file
File has been completed now
notify all readers
Reader 1: File has been completed now!! you can read it
Reader 2: File has been completed now!! you can read it
|