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

多线程概述

Java是一个支持多线程的开发语言,多线程并发执行任务可以充分利用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方法只能在同步代码块中使用,在非同步代码块中会导致异常

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

完。

发布了27 篇原创文章 · 获赞 27 · 访问量 4272

猜你喜欢

转载自blog.csdn.net/qq_41788977/article/details/103446286