为什么编译器不抱怨在非同步块中使用等待
Why compiler doent complain for wait used in non-synchronised block
据我所知,当我们想在 java 中调用 wait
时,我们需要同步 API/block 否则它将在 IllegalMonitorStateException
中结束 运行 时间。我的问题是,既然我们确信它总是导致异常,为什么编译器不抱怨它?
因为您可能一直在调用堆栈中较高位置的同步块中调用具有 wait
的方法。编译器只能找到代码的语法有效性 - 它无法检查逻辑错误。
因为:
- 开发人员有责任确保代码合乎逻辑
- 开发一个编译器来处理所有潜在的微不足道的错误会花费太多时间和精力
- 这样的编译器不会流行,因为它们需要很长时间才能编译
编译器无法检测到此错误。它不是语言的静态语义。它根本不是语言的语义,实际上,它是运行时库的语义。
As :同步可能发生在调用堆栈的较高位置。作为一个直观的例子,对于 不可能 检测调用是否合法的情况:
class Example
{
private final Object lock = new Object();
private void run() throws InterruptedException
{
if (Math.random() > 0.5)
{
synchronized (lock)
{
doWait();
}
}
else
{
doWait();
}
}
private void doWait() throws InterruptedException
{
lock.wait();
}
}
您根本不知道调用是否发生在 synchronized
块内部。
wait()
是对象 class 的一部分,因此我们可以直接调用它。在线程中,没有类似 throws 子句的东西来指示编译器该方法应该被同步块包围。
据我所知,当我们想在 java 中调用 wait
时,我们需要同步 API/block 否则它将在 IllegalMonitorStateException
中结束 运行 时间。我的问题是,既然我们确信它总是导致异常,为什么编译器不抱怨它?
因为您可能一直在调用堆栈中较高位置的同步块中调用具有 wait
的方法。编译器只能找到代码的语法有效性 - 它无法检查逻辑错误。
因为:
- 开发人员有责任确保代码合乎逻辑
- 开发一个编译器来处理所有潜在的微不足道的错误会花费太多时间和精力
- 这样的编译器不会流行,因为它们需要很长时间才能编译
编译器无法检测到此错误。它不是语言的静态语义。它根本不是语言的语义,实际上,它是运行时库的语义。
As
class Example
{
private final Object lock = new Object();
private void run() throws InterruptedException
{
if (Math.random() > 0.5)
{
synchronized (lock)
{
doWait();
}
}
else
{
doWait();
}
}
private void doWait() throws InterruptedException
{
lock.wait();
}
}
您根本不知道调用是否发生在 synchronized
块内部。
wait()
是对象 class 的一部分,因此我们可以直接调用它。在线程中,没有类似 throws 子句的东西来指示编译器该方法应该被同步块包围。