另一个棘手的核心 Java 问题,wait 和 notify。它们是在有 synchronized 标记的方法或 synchronized 块中调用的,因为 wait 和 modify 需要监视对其上调用 wait 或 notify-get 的 Object。大多数Java开发人员都知道对象类的 wait(),notify() 和 notifyAll()方法必须在Java中的 synchronized 方法或 synchronized 块中调用, 但是我们想过多少次, 为什么在 Java 中 wait, notify 和 notifyAll 来自 synchronized 块或方法?最近这个问题在Java面试中被问到我的一位朋友,他思索了一下,并回答说: 如果我们不从同步上下文中调用 wait() 或 notify() 方法,我们将在 Java 中收到 IllegalMonitorStateException。他的回答从实际效果上年是正确的,但面试官对这样的答案不会完全满意,并希望向他解释这个问题。面试结束后 他和我讨论了同样的问题,我认为他应该告诉面试官关于 Java 中 wait()和 notify()之间的竞态条件,如果我们不在同步方法或块中调用它们就可能存在。让我们看看竞态条件如何在Java程序中发生。它也是流行的线程面试问题之一,并经常在电话和面对面的Java开发人员面试中出现。因此,如果你正在准备Java面试,那么你应该准备这样的问题,并且可以真正帮助你的一本书是《Java程序员面试公式书》的。这是一本罕见的书,涵盖了Java访谈的几乎所有重要主题,例如核心Java,多线程,IO 和 NIO 以及 Spring 和 Hibernate 等框架。你可以在这里查看。为什么要等待来自 Java中的 synchronized 方法的 wait方法为什么必须从 Java 中的 synchronized 块或方法调用 ?我们主要使用 wait(),notify() 或 notifyAll() 方法用于 Java 中的线程间通信。一个线程在检查条件后正在等待,例如,在经典的生产者 - 消费者问题中,如果缓冲区已满,则生产者线程等待,并且消费者线程通过使用元素在缓冲区中创建空间后通知生产者线程。调用notify()或notifyAll()方法向单个或多个线程发出一个条件已更改的通知,并且一旦通知线程离开 synchronized 块,正在等待的所有线程开始获取正在等待的对象锁定,幸运的线程在重新获取锁之后从 wait() 方法返回并继续进行。让我们将整个操作分成几步,以查看Java中wait()和notify()方法之间的竞争条件的可能性,我们将使用Produce Consumer 线程示例更好地理解方案:

  • Producer 线程测试条件(缓冲区是是否完整)并确认必须等待(找到缓冲区已满)。
  • Consumer 线程在使用缓冲区中的元素后设置条件。
  • Consumer 线程调用 notify() 方法; 这是不会被听到的,因为 Producer 线程还没有等待。
  • Producer 线程调用 wait() 方法并进入等待状态。

因此,由于竞态条件,我们可能会丢失通知,如果我们使用缓冲区或只使用一个元素,生产线程将永远等待,你的程序将挂起。“在java同步中等待 notify 和 notifyall 现在让我们考虑如何解决这个潜在的竞态条件?这个竞态条件通过使用 Java 提供的 synchronized 关键字和锁定来解决。为了调用 wait(),notify() 或 notifyAll(), 在Java中,我们必须获得对我们调用方法的对象的锁定。由于 Java 中的 wait() 方法在等待之前释放锁定并在从 wait() 返回之前重新获取锁定方法,我们必须使用这个锁来确保检查条件(缓冲区是否已满)和设置条件(从缓冲区获取元素)是原子的,这可以通过在 Java 中使用 synchronized 方法或块来实现。我不确定这是否是面试官实际期待的,但这个我认为至少有意义,请纠正我如果我错了,请告诉我们是否还有其他令人信服的理由调用 wait(),notify() 或 Java 中的 notifyAll() 方法。总结一下,我们用 Java 中的 synchronized 方法或 synchronized 块调用 Java 中的 wait(),notify() 或 notifyAll() 方法来避免:1) Java 会抛出 IllegalMonitorStateException,如果我们不调用来自同步上下文的wait(),notify()或者notifyAll()方法。2) Javac 中 wait 和 notify 方法之间的任何潜在竞争条件。

最新文章

  1. iOS开发Swift篇—(九)属性
  2. android中xmlns:tools属性详解
  3. adb uninstall卸载apk 命令后跟的是包的名称
  4. 遍历页面上所有TextBox,并赋值为String.Empty
  5. Unity FixedUpdate 与 Update 的线程关系实验
  6. setAction方法 Snackbar 右侧按钮可以被点击并处理一些事件
  7. JPA 系列教程5-双向一对多
  8. Azure SQL Database (25) Azure SQL Database创建只读用户
  9. ajax初探--实现简单实时验证
  10. 程序员听到bug后的N种反应,太形象了
  11. springboot+mybatis+thymeleaf项目搭建及前后端交互
  12. 如何猜出 Y combinator
  13. Intent Activity跳转 传递数据 Bundle
  14. SQL 2012 分页取数据
  15. Linux基础操作-分区概念
  16. How many ways??---hdu2157(矩阵快速幂)
  17. java拾遗4----一个简单java程序的运行全过程
  18. 在 Windows Azure 上设计多租户应用程序
  19. TCP/IP三次握手与四次握手
  20. oracle 里 插入空字符串会被转成null插入

热门文章

  1. Redis持久化、主从与哨兵架构详解
  2. MySQL数据库的导入方法
  3. Asp.net core IdentityServer4与传统基于角色的权限系统的集成
  4. Springboot整合kaptcha验证码
  5. 渗透测试工具篇之目录扫描工具dirmap
  6. [题解]Mail.Ru Cup 2018 Round 1 - C. Candies Distribution
  7. SaaS平台是什么,为什么字节、腾讯等大厂都在抢相关人才
  8. 基于mysql的报表工具有哪些?值得推荐的mysql报表工具
  9. 第一次打开pycharm运行python文件报错”No Python interpreter selected“问题的解决办法
  10. 2020.9.28 多进程multiprocess 进程池pool 子进程subprocess 进程间通信