您可能已经注意到 Object 类具有三个 final 方法,分别称为 wait、notify 和 notifyAll。这些方法用于线程间通信。Java 5 引入了执行器框架,它为您处理线程间通信,并在内部使用 wait、notify 和 notifyAll,但您仍然需要基本了解这些方法以及 java 中使用 wait、notify 和 notifyAll 的线程间通信如何工作。

什么是 wait 、 notify 和 notifyAll 方法?

wait 、 notify 和 notifyAll 方法用于允许线程通过访问公共对象来相互通信,或者换句话说,可以将 Object 视为通过这些方法进行线程间通信的媒介。这些方法需要从同步上下文中调用,否则会抛出 java.lang.IllegalMonitorStateException。

同步块的一些背景:

  • 在同步块中一次只能进入一个线程
  • 线程需要锁定对象才能进入同步块。
  • 如果线程 A 想要进入同步块,那么线程 A 必须等待线程 B 释放它。

让我们对这些方法有一些简要的了解:

wait():

当您在对象上调用 wait 方法时,它会告诉线程放弃锁定并进入睡眠状态,除非并且直到某个其他线程进入同一监视器并在其上调用 notify 或 notifyAll 方法。

notify():

当您在对象上调用 notify 方法时,它会唤醒等待该对象的线程之一。因此,如果多个线程正在等待一个对象,它将唤醒其中一个。现在你一定想知道它会唤醒哪一个。它实际上取决于操作系统的实现。

notifyAll() :

notifyAll 将唤醒等待该对象的所有线程,不像 notify 只唤醒其中一个。哪个将首先唤醒取决于线程优先级和操作系统实现。

让我们借助示例来理解它:

1. 创建一个名为 Book.java 的类: 这是一个 java bean 类,线程将在该类上执行并调用 wait 和 notify 方法。

package org.arpit.java2blog.thread;public class Book {String title;
boolean isCompleted;public Book(String title) {super();this.title = title;
}public String getTitle() {return title;
}
public void setTitle(String title) {this.title = title;
}
public boolean isCompleted() {return isCompleted;
}
public void setCompleted(boolean isCompleted) {this.isCompleted = isCompleted;
}}

2. 创建一个名为 BookReader.java 的类

这个线程会一直等到其他线程调用notify方法,然后才会完成它的处理。它将首先锁定 book 对象,并从同步块中调用。因此在此示例中,它将等待 BookWriter 完成这本书。

ackage org.arpit.java2blog.thread;public class BookReader implements Runnable{Book book;public BookReader(Book book) {super();this.book = book;
}@Override
public void run() {synchronized (book) {System.out.println(Thread.currentThread().getName()+" is waiting for the book to be completed: "+book.getTitle());try {book.wait();} catch (InterruptedException e) {    e.printStackTrace();}System.out.println(Thread.currentThread().getName()+": Book has been completed now!! you can read it");}
}}

3. 创建一个名为 BookWriter.java 的类

此类将通知正在等待书籍对象的线程(在通知的情况下)。它不会在调用 notify 后立即放弃锁,它首先完成其同步块。所以在这个例子中,BookWriter 将完成这本书并将其通知给 BookReaders。

package org.arpit.java2blog.thread;
public class BookWriter implements Runnable{Book book;public BookWriter(Book book) {super();this.book = book;
}@Override
public void run() {synchronized (book) {System.out.println("Author is Starting book : " +book.getTitle() );try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}book.setCompleted(true);System.out.println("Book has been completed now");book.notify();System.out.println("notify one reader");}
}
}

4. 创建一个类ThreadInterCommunicationMain,java。 这是我们的主类,它将创建上述类的对象并运行它。

package org.arpit.java2blog.thread;public class ThreadInterCommunicationMain {public static void main(String args[])
{// Book object on which wait and notify method will be calledBook book=new Book("The Alchemist");BookReader johnReader=new BookReader(book);BookReader arpitReader=new BookReader(book);// BookReader threads which will wait for completion of bookThread johnThread=new Thread(johnReader,"John");Thread arpitThread=new Thread(arpitReader,"Arpit");arpitThread.start();johnThread.start();// To ensure both readers started waiting for the booktry {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}// BookWriter thread which will notify once book get completedBookWriter bookWriter=new BookWriter(book);Thread bookWriterThread=new Thread(bookWriter);bookWriterThread.start();}}

如果是 notify(): 当你运行上面的程序时,你会得到以下输出:

Arpit is waiting for the book to be completed: The Alchemist
John is waiting for the book to be completed: The Alchemist
Author is Starting book : The Alchemist
Book has been completed now
notify one reader
Arpit: Book has been completed now!! you can read it

所以在这里,两个 BookReader 线程(arpit 和 john)正在等待 book 完成,所以他们调用 book.wait()。一旦 BookWriter 完成它,它调用 book.notify() 并且 arpit 线程启动并完成它的处理。

在 notifyAll() 的情况下: 让我们将 BookWriter 类更改为调用 book.notifyAll()。

package org.arpit.java2blog.thread;public class BookWriter implements Runnable{Book book;public BookWriter(Book book) {super();this.book = book;
}@Override
public void run() {synchronized (book) {System.out.println("Author is Starting book : " +book.getTitle() );try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}book.setCompleted(true);System.out.println("Book has been completed now");book.notifyAll();System.out.println("notify readers");}
}}

当你运行上面的程序时,你会得到以下输出:

Arpit is waiting for the book to be completed: The Alchemist
John is waiting for the book to be completed: The Alchemist
Author is Starting book : The Alchemist
Book has been completed now
notify readers
John: Book has been completed now!! you can read it
Arpit: Book has been completed now!! you can read it

在 notifyAll() 的情况下,它会通知所有等待该对象的线程。

lilnk:第五章 Java 中的 wait、notify 和 notifyAll 方法示例 | 编程字典

第五章 Java 中的 wait、notify 和 notifyAll 方法示例相关推荐

  1. 第五章 Java中的String类和StringBuffer(上)

    为什么不从第一章开始记录? 因为,博主最近在刷"蓝桥杯"的算法题,题目中遇到了许多和字符串相关的题目. 比如:要求程序对用户输入的串进行处理.具体规则如下: 1.  把每个单词的首 ...

  2. 【慕课笔记】第五章 JAVA中的集合框架(中) 第1节 MapHashMap简介

    第1节 Map&HashMap简介 Map接口 Map提供了一种映射关系,其中的元素是以键值对的形式存储的,能够实现根据key快速查找value Map中的键值对以Entry类型的对象实例形式 ...

  3. (Java零基础学习笔记)第二章 Java中的基本语法

    前言: 大家好! 我是BA unravel .如果你想和我一起学习JAVA,欢迎大家一起来学习这个世界上最好的语言! 学习目标: 一周掌握 Java 入门知识 学习内容: 1. 搭建 Java 开发环 ...

  4. java 中的wait notify

    Wait&Notify 以下内容来自<Java并发编程的艺术>,4.3.2 等待/通知机制 线程A等待某一个变量_v_满足某个条件,而线程B会在某个不确定的时刻修改_v_,以使其满 ...

  5. 《SVN宇宙版教程》:第五章 TortoiseSVN中Repo-browser介绍

    第五章 TortoiseSVN中Repo-browser介绍 导言: 窗口Repo-browser是TortoiseSVN提供的一个管理工作副本或仓库文件的工具,此窗口在使用TortoiseSVN工具 ...

  6. 为什么wait、notify、notifyAll方法定义在Object中而不是Thread类中

    多线程概述 Java是一个支持多线程的开发语言,多线程并发执行任务可以充分利用CPU资源,提高多任务并发执行效率(注意区分:多线程并不会加快任务的执行速度,而是可以充分利用多核CPU让线程轮流进行工作 ...

  7. java语言 文件上传,java中实现文件上传的方法

    java中实现文件上传的方法 发布时间:2020-06-19 10:29:11 来源:亿速云 阅读:86 作者:Leah 这篇文章给大家分享的是java中实现文件上传的方法,相信大部分人都还没学会这个 ...

  8. Java中创建数组的几种方法

    Java中创建数组的几种方法 public static void main(String[] args) { //创建数组的第一种方法 int[] arr=new int[6]; int intVa ...

  9. 高级 | Java中获取类名的3种方法

    转载自 高级 | Java中获取类名的3种方法 获取类名的方法 Java 中获取类名的方式主要有以下三种. getName() 返回的是虚拟机里面的class的类名表现形式. getCanonical ...

最新文章

  1. LabVIEW机器视觉系统图像畸变、校准和矫正(基础篇—3)
  2. Objetive-C +load方法研究
  3. 开源项目-基于Intel VT技术的Linux内核调试器
  4. LeetCode Convert Sorted List to Binary Search Tree(有序单链表转为平衡二叉树)
  5. 定题信息服务是从什么角度_格木教育谢浩浩:事业单位综合应用概念分析题之角度界定技巧...
  6. springboot 读取application.properties流程
  7. Python 中实用却不常见的小技巧!
  8. PAT 1009 说反话
  9. Excel VBA 处理图形图表详解
  10. 琉璃男主成毅手机壁纸,你要么?
  11. 【答辩问题】计算机专业本科毕业设计答辩的一般程序3
  12. OpenStack云第三天
  13. VPP TCP定时器
  14. python opencv合并图片
  15. 等比数列求和python_Python科学计算
  16. 公关,从讲好一个故事开始
  17. 专科计算机网络技术综述,高职高专计算机系列教材:计算机网络技术
  18. 模型评估之过拟合与欠拟合
  19. python中set option_pd.set_option
  20. 先用总分升序再用计算机降序,怎样用升序降序给EXCEL排名

热门文章

  1. 分布式系统架构(一)——三大理论
  2. java的单步调试_Eclipse调试Java程序 可用于单步调试
  3. 卡轨式2光8电千兆工业级环网交换机嵌入式低功耗网管型矿用工业以太网交换机
  4. 天了噜!程序媛离职,为宣泄不满rm-f×删库,客运总站瘫痪 6 个小时
  5. skip-gram负采样原理
  6. 梁启超家书致思成书-人生之旅途历途甚长,所争决不在一年半月
  7. Maven项目的介绍、入门搭建
  8. python 命名规范_python命名规范
  9. 记一次破解自己win10登录密码的经历
  10. 虹软人脸识别-SpringBoot集成