为什么wait,notify和notifyAll是Object类中的方法,不像Cloneable

时间:2017-03-28 14:35:35

标签: java multithreading oop jvm java-threads

最近,我在采访中被问到为什么使用了waitnotifynotifyAll。我解释了他们。

之后他们让我假设一个应用程序总是单线程的。真的需要吗?我的回答是否定的。

然后,他们问为什么waitnotifynotifyAll这样的设计是Object类的方法。为什么Java没有接口,并且这些方法在该接口中,并且哪个类想要实现它可以使用它。所以,我有点卡住,无法思考这个设计。有人可以为此播种吗?

4 个答案:

答案 0 :(得分:2)

JVM使用操作系统级线程。这意味着每个具体操作系统的每个具体JVM都以不同方式处理线程。这些方法不仅在Object类中实现,它们被标记为native,这意味着它们在JVM的系统层中实现。

如果这些方法在某个界面中,那就意味着任何人都可以重新定义它们。

答案 1 :(得分:0)

等待并通知和notifyAll不仅仅是普通方法或同步实用程序,更重要的是它们是Java中两个线程之间的通信机制。如果通过任何java关键字(例如synchronized)无法使用此机制,那么Object类是使它们可用于每个对象的正确位置。记住同步和等待通知是两个不同的区域,不要混淆它们是相同的或相关的。同步是提供互斥并确保Java类的线程安全,如等待和通知是两个线程之间的通信机制。

答案 2 :(得分:0)

  

然后,他们问为什么waitnotifynotifyAll这样的设计是Object类的方法。为什么Java没有接口,并且这些方法在该接口中,并且哪个类想要实现它可以使用它。

所有这些方法都是在本机代码中实现的,并且它们与包装它们的synchronized块紧密集成。它们是Java语言定义的一部分,具有程序员所依赖的特定行为。它们不适合作为任何对象实现的接口方法。

当一个对象在另一个对象上调用obj.wait();时,它不必担心wait的实现。它需要确保它对该对象具有互斥锁,以便它可以对它或其他存储进行关键更新,如果wait方法是由对象本身实现的,那么该对象可能违反语言要求并且例如,允许多个线程同时进入受保护的块。线程可以synchronize并在另一个对象上调用wait / notify / notifyAll,而不必担心该对象是否已适当地实现了这些方法。通过在final上创建Object方法,无论对象类型或本地实现如何,行为都将起作用。

另外,正如我所提到的,wait / notify / notifyAll与周围的synchronized块紧密集成。当wait()中的某个线程被阻塞时,周围的synchronized锁被释放,以便其他线程可以访问受保护的块。如果wait()只是一个没有其他奇怪语言特征的简单方法调用,那么这种协调是不可能的。

这让我想起了我的另一个答案:Concept behind putting wait(),notify() methods in Object class

答案 3 :(得分:0)

从一开始就是Java程序将是多线程的设计目标。请记住,Java的计划是使嵌入式编程不那么令人生畏,整个服务器端Web应用程序(导致Sun核心业务的商品化)是一个意外。

由于目标是创建可与其他设备通信的嵌入式应用程序,因此必须采用多线程才能实现网络友好和事件驱动。但是编写高效的多线程服务器在java列表中并不高。

Java长期以来没有ReentrantLock或非阻塞i / o。最初可用的主要数据结构是Vector,Hashtable和StringBuffer(所有这些都已在所有公共方法上同步)。从这个选择来看,似乎目标是足够好的,而不是尽可能高效。后来很明显,Java需要对服务器应用程序的使用情况更有效,并且1.2引入了不同步的Vector和Hashtable的等价物。这似乎是一种事后的想法,一旦显然Java有一个以前没有设计过的新角色,就会进行课程调整。

如果Java留在了利基市场,那么它可能就已经足够了。似乎最初的计划仅针对内部锁定,因此锁定也可以连接到Object。