最近,我在采访中被问到为什么使用了wait
,notify
和notifyAll
。我解释了他们。
之后他们让我假设一个应用程序总是单线程的。真的需要吗?我的回答是否定的。
然后,他们问为什么wait
,notify
和notifyAll
这样的设计是Object
类的方法。为什么Java没有接口,并且这些方法在该接口中,并且哪个类想要实现它可以使用它。所以,我有点卡住,无法思考这个设计。有人可以为此播种吗?
答案 0 :(得分:2)
JVM使用操作系统级线程。这意味着每个具体操作系统的每个具体JVM都以不同方式处理线程。这些方法不仅在Object
类中实现,它们被标记为native
,这意味着它们在JVM的系统层中实现。
如果这些方法在某个界面中,那就意味着任何人都可以重新定义它们。
答案 1 :(得分:0)
等待并通知和notifyAll不仅仅是普通方法或同步实用程序,更重要的是它们是Java中两个线程之间的通信机制。如果通过任何java关键字(例如synchronized)无法使用此机制,那么Object类是使它们可用于每个对象的正确位置。记住同步和等待通知是两个不同的区域,不要混淆它们是相同的或相关的。同步是提供互斥并确保Java类的线程安全,如等待和通知是两个线程之间的通信机制。
答案 2 :(得分:0)
然后,他们问为什么
wait
,notify
和notifyAll
这样的设计是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。