Java中notify和NotifyAll之间的区别

时间:2020-02-23 14:34:06  来源:igfitidea点击:

在本教程中,我们将看到在Java中 notifynotifyall的区别。

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()的情况下,它将通知所有线程等待该对象。