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

多线程概述

Java是一个支持多线程的开发语言,多线程并发执行任务可以充分利用CPU资源,提高多任务并发执行效率(注意区分:多线程并不会加快任务的执行速度,而是可以充分利用多核CPU让线程轮流进行工作,达到了一种“同时”工作的效果)。

并发时的产生问题

多线程在执行时,会遇到一些问题,问题的关键原因则是在共享资源的更新操作上容易产生冲突。

解决的方向

解决冲突的方式则是从共享资源的占用机制入手,保证共享资源同一时刻只能被一个线程占用,从而达到数据一致。

具体实现方式中的一种

在Java中提供了synchorinzed关键字,在该关键字修饰的代码内,称为同步代码块,线程执行该区域代码需要获取锁,在获取成功之后,其他线程需要等该线程执行完毕释放锁之后才能获取到。

wait、notify、notifyAll方法的作用

在同步代码块中,可以使用wait、notify来控制当前占用资源的线程进入阻塞队列与唤醒进入就绪队列
也就是说,上述两个方法实际上实现的时线程之间的通信机制,用来通知线程的阻塞与唤醒。

引出问题:为什么定义在Object中而不是Thread类

线程为了进入临界区(也就是同步块内),需要获得锁并等待锁可用,它们并不知道也不需要知道哪些线程持有锁,它们只需要知道当前资源是否被占用,是否可以获得锁,所以锁的持有状态应该由同步监视器来获取,而不是线程本身。

一个比喻

形象的比喻:一个女孩子同时被10个男孩子追,在同一个时间段内只能陪一个男孩子看电影,当其中一个男孩想要邀请女孩看电影时,应该由女孩子来通知男孩子,这个时间段可不可以赴约,而不应该是男孩子询问其他情敌抑或是由情敌之间相互通知谁该去赴约(那还不打起来了)。
例子中女孩相当于”共享资源“(每一个男孩机会均等),在Java中是一个对象,男孩子们相当于线程,多个线程之间的通信机制,由共享资源(就是前文所说的同步监视器)来实现,即将wait、notify、notifyAll方法定义在Object中是最合理的

较详细的解释

以下是一篇英文博客的翻译:
为什么它们不应该在Thread类,(我)的一些想法是:

  1. wait和nofity不是常见的普通java方法或同步工具,在Java中它们更多的是实现两个线程之间的通信机制。
    如果不能通过类似synchronized这样的Java关键字来实现这种机制,那么Object类中就是定义它们最好的地方,以此来使任何Java对象都可以拥有实现线程通信机制的能力。
    记住synchronized和wait,notify是两个不同的问题域,并且不要混淆它们的相似或相关性。 同步类似竞态条件,是提供线程间互斥和确保Java类的线程安全性的,而wait和notify是两个线程之间的通信机制。

  2. 另一个原因:每个对象都可以作为锁

  3. 在Java中,为了进入临界区代码段,线程需要获得锁并且它们等待锁可用,它们不知道哪些线程持有锁而它们只知道锁是由某个线程保持,它们应该等待锁而不是知道哪个线程在同步块内并要求它们释放锁。 这个比喻适合等待和通知在object类而不是Java中的线程。

这些只是我的想法为什么wait和notify方法在Object类中声明,而不是Java中的Thread,当然你可以有不同的观点。

在现实中,它就是Java不支持操作符重载一样,只是Java设计者做的一个设计决定。 无论如何,如果你有任何其它令人信服的理由请发布出来。

还有一点需要注意:wait、notify、notifyAll方法只能在同步代码块中使用,在非同步代码块中会导致异常

因为只有在同步代码块中才会涉及到锁的概念,在非并发环境下尝试操作锁会导致失败。

相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页