Java中notify和NotifyAll之间的区别
时间:2020-02-23 14:34:06 来源:igfitidea点击:
在本教程中,我们将看到在Java中 notify和 notifyall的区别。
notify():
在对象上调用通知方法时,它会唤醒等待该对象的一个线程。
因此,如果多个线程正在等待一个对象,它将唤醒其中一个。
现在你必须想知道它会醒来的哪一个。
它实际上取决于OS实现。
NotifyAll():
NotifyAll将唤醒等待该对象的所有线程,与通知仅唤醒其中一个。
唤醒首先唤醒,取决于线程优先级和OS实现。
让我们通过示例来理解:
1.创建名为file.java的类:
它是java bean类,其中线程将采用和调用等待和通知方法。
package org.arpit.theitroad.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.创建名为filereader.java的类
此线程将等到其他线程呼叫通知方法,然后在完成其处理之后。
它首先将在文件对象上锁定锁,并将从同步块调用。
所以,它将等待文件机完成文件。
package org.arpit.theitroad.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.创建一个名为filewriter.java的类
此类将通知线程(如果是通知),它正在等待文件对象。
它不会在调用通知时立即放弃锁定,它首先完成其同步块。
因此,在此示例中,FileWriter将完成该文件并将其通知给Finereaders。
package org.arpit.theitroad.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.创建类NotifyAnnotifyAllMain
这是我们的main类,它将创建上述类的对象并运行它。
package org.arpit.theitroad.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();
}
}
运行上面的程序时,我们将获取以下输出:
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
所以其中两个Finereader线程(读者1和读者2)正在等待完成文件,因此它们调用file.wait()。
一旦文件机完成了它的文件,它称为file.notify()和阅读器2线程启动并完成其处理。
在NotifyAll()的情况下:
允许更改文件类调用文件.NotifyAll()。
package org.arpit.theitroad.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");
}
}
}
运行上面的程序时,我们将获取以下输出:
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
在NotifyAll()的情况下,它将通知所有线程等待该对象。

