作者:Yujiaao

来源:segmentfault.com/a/1190000019962661

一个较难回答的 Java 问题, Java 编程语言又不是你设计的,你如何回答这个问题呢?需要对 Java 编程的常识进行深入了解才行。

这个问题的好在它能反映面试者是否对 wait - notify 机制有没有了解, 以及他相关知识的理解是否明确。就像为什么 Java 中不支持多继承或者为什么 String 在 Java 中是 final 的问题一样,这个问题也可能有多个答案。

为什么在 Object 类中定义 wait 和 notify 方法,每个人都能说出一些理由。

从我的面试经验来看, wait 和 nofity 仍然是大多数Java 程序员最困惑的,特别是2到3年的开发人员,如果他们要求使用 wait 和 notify, 他们会很困惑。

因此,如果你去参加 Java 面试,请确保对 wait 和 notify 机制有充分的了解,并且可以轻松地使用 wait 来编写代码,并通过“生产者-消费者”问题或实现阻塞队列等了解通知的机制。

为什么等待和通知需要从同步块或方法中调用, 以及 Java 中的 wait,sleep 和 yield 方法之间的差异,如果你还没有读过相关知识,一定要看看。

为何 wait,notify 和 notifyAll 属于 Object 类? 为什么它们不应该在 Thread 类中? 以下观点我认为是有道理的:

1) wait 和 notify 不仅仅是普通方法或同步工具,更重要的是它们是 Java 中两个线程之间的通信机制。

对语言设计者而言, 如果不能通过 Java 关键字(例如 synchronized)实现通信此机制,同时又要确保这个机制对每个对象可用, 那么 Object 类则是的合理的声明位置。

记住同步和等待通知是两个不同的领域,不要把它们看成是相同的或相关的。同步是提供互斥并确保 Java 类的线程安全,而 wait 和 notify 是两个线程之间的通信机制。

2) 每个对象都可上锁,这是在 Object 类而不是 Thread 类中声明 wait 和 notify 的另一个原因。

3) 在 Java 中,为了进入代码的临界区,线程需要锁定并等待锁,他们不知道哪些线程持有锁,而只是知道锁被某个线程持有, 并且需要等待以取得锁, 而不是去了解哪个线程在同步块内,并请求它们释放锁。

4) Java 是基于 Hoare 的监视器的思想:

http://en.wikipedia.org/wiki/Monitor_%28synchronization%29

在Java中,所有对象都有一个监视器。

线程在监视器上等待,为执行等待,我们需要2个参数:

  • 一个线程

  • 一个监视器(任何对象)

在 Java 设计中,线程不能被指定,它总是运行当前代码的线程。但是,我们可以指定监视器(这是我们称之为等待的对象)。

这是一个很好的设计,因为如果我们可以让任何其他线程在所需的监视器上等待,这将导致“入侵”,影响线程执行顺序,导致在设计并发程序时会遇到困难。

请记住,在 Java 中,所有在另一个线程的执行中造成入侵的操作都被弃用了(例如 Thread.stop 方法)。

为什么 wait/notify/notifyAll 在 Object 类定义而不是 Thread 类?相关推荐

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

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

  2. wait/notify/notifyAll在Object类中

    wait/notify/notifyAll在Object类中 因为我们在使用synchronized锁 对象锁可以是任意对象,所以wait/notify/notifyAll需要放在Object类中. ...

  3. java组合类,对象组合,定义一个点类,将圆的圆心用点类的对象表示,则圆类定义为一个组合类,仍然能计算圆的面积和周长,并能对圆进行移动。

    对象组合的概念 如果一个对象中的域是其他类的对象,则称这个对象是组合对象,组合对象所在的类是组合类.例如计算机是由其他部件(对象)组成的.通过组合的方式,可以简化对象的创建过程,提高对象的创建效率.从 ...

  4. python类定义的讲解_python类定义的讲解

    Python中的类属性和对象属性的区别详解 类属性: class Employee(object): emCount=0 def __init__(self,name,salary): self.na ...

  5. java类定义的顺序_Java类及对象的初始化顺序

    1.初始化规则: 下面规则优先级从前往后依次降低 0.加载一个类时先初始化基类后初始化扩展类: 1.类的初始化高于对象的初始化: 类的初始化依靠静态代码(被static标识的),静态代码块.静态变量这 ...

  6. python类的使用(类定义,构造器,类属性,方法)

    注:这里只描述使用方法,具体类的概念长篇大论就不要为难我这个懒人了. 总之一句话编程语言只是一个工具,会用就行,好用就行.打破砂锅问到底,我觉得有必要研究一下C,汇编,电子链路等. class clt ...

  7. java box类定义三变量_01.类的成员变量:\n设计一个立方体类Box,定义三个属性,分别是长,宽,高。定义二个方法,分别计...

    01.类的成员变量:\n设计一个立方体类Box,定义三个属性,分别是长,宽,高.定义二个方法,分别计算并输出立方体的体积和表面积 答:java.util.Scanner; public class B ...

  8. Java程序定义一个继承Thread类,并覆盖run()方法,在run()方法中每隔100毫秒打印一句话。

    package javase18;public class javase18_1 extends Thread{public void run(){try{String[] a={"Hell ...

  9. java多线程notifyall_Java多线程:线程状态以及wait(), notify(), notifyAll()

    1. wait(), notify(), notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前 ...

最新文章

  1. linux显卡驱动mxm,linux下我的FX5200显卡驱动安装
  2. 计算机视觉 模型、学习和推理 Computer vision:models,learning and inference(免费下载)
  3. Memcached的基础梳理
  4. 16-1 Redis分布式缓存引入与保存缓存功能实现
  5. solidworks模板_工程师实用高级操作,Solidworks自定义属性链接到工程图模板
  6. jmeter模拟登陆
  7. 腾讯安全团队深入解析wannacry蠕虫病毒
  8. Python文件与函数练习题
  9. Package has no installation candidate
  10. 几种典型的智慧农业物联网解决方案
  11. YYUC输出联动select标签
  12. 软件测试职业目标具体计划范文,关于测试的工作计划
  13. Android:EditText 设置弹出数字输入法键盘
  14. git之如何合并部分提交
  15. linux vi 保存退出与不保存退出
  16. opecv BGR转NV21
  17. 最新版百度网盘,下载提速方法
  18. 屏幕截图 take screenshot
  19. Android - 键值对存储 SharedPreference、DataStore、MMKV
  20. java总结——什么是重载

热门文章

  1. 04.Java网络编程(转载)
  2. percona-xtrabackup工具实现mysql5.6.34的主从同步复制
  3. Disruptor是一个高性能的异步处理框架
  4. mysql explain 解释
  5. iReport中求和的问题
  6. linux命令之查看动态库中字符串-strings
  7. libQtCore.so.4相关错误
  8. caffe学习(五):cifar-10数据集训练及测试(Ubuntu)
  9. Zedboard学习(三):PL下流水灯实验
  10. mysql数据丢失_图解MySQL | 「原理解析」 MySQL使用固定的server_id导致数据丢失