当前位置: 首页 > 知识库问答 >
问题:

为什么我不能直接访问(并锁定)Objects用于同步块的隐式锁

慕阳伯
2023-03-14

为清楚起见,改写为准

我希望能够通过在适当的时候直接调用lock和release方法,将同步块的使用与更明确的锁定结合起来。因此,当我可以轻松使用sychtronized(myObject)时,我可以使用sychtornized的语法优势,但也可以调用myObject.lock

我知道每个对象都隐含地内置了一个租用锁,该锁由同步块使用。实际上,每次进入同步块时,都会在对象内部重入锁上校准锁定,并在离开同步块时在同一重入锁上调用解锁。我似乎很容易允许一个人手动锁定/解锁这个非法的可进入锁;从而允许混合同步块和显式锁定。

但是,据我所知,没有办法做到这一点。由于同步块的工作方式,我不相信有一种方便的方法可以将它们与显式锁定othewrise混合在一起。似乎这将是一个相当方便的,并且通过扩展Object api来添加锁定/解锁方法很容易添加。

我的问题是,为什么这不存在?我确信这是有原因的,但我不知道这是什么。我认为问题可能出在封装上。同样的原因,你不想做同步(这个)。但是,如果我已经将系统化(myObject)称为系统化(myObject),那么通过定义,任何了解myObject的人都可以同样同步它并导致死锁,如果愚蠢地完成。封装问题归结为谁可以访问您同步的对象,而不管您使用同步块还是手动锁定对象;至少在我看来是这样。那么,不允许手动锁定对象还有其他好处吗?

共有1个答案

斜昊空
2023-03-14

某个对象的锁与实例本身高度相关。同步块和方法的结构非常严格。如果作为程序员,您可能会干扰系统(虚拟机),这可能会导致严重的问题。

  • 您最终可以释放由同步块创建的锁
  • 您创建了另一个同步块将释放的锁
  • 您创建的锁定条目多于出口
  • 您创建的锁定出口多于条目

甚至还为锁定释放操作定义了特定的字节码。如果您有此锁定/解锁操作的“方法”,则应将其编译为这些字节码。因此,它实际上是一个低级操作,与其他Java对象级实现有很大不同。

同步是一个非常强的契约。我认为JLS的设计者不想让这种可能性打破这个合同。

JLS 的第 17 章描述了更多关于预期行为的信息。

 类似资料:
  • 我正在修改我以前使用的Visitor模式。我们有基类Element,它有虚拟方法接受(Visitor),并且这个方法在继承自Element的所有类中都被重写。在任何派生类中,接受()所做的就是调用visitor- 为什么客户不能直接打电话给访客- 调用元素中有哪些有用的信息。接受(访客),然后依次呼叫访客。参观(元素)?这使得Visitor模式的使用很麻烦,并且在所有元素类的层次结构中都需要额外的

  • 我正在尝试与selenium webDrive同步,但某些东西无法隐含地使用等待()。 我隐含理解的方式等待(...)是代码正在等待,直到元素在最大时间内可用。 以下代码因错误而崩溃: 系统。out ist打印:-- 我也用Geckodriver试过了,结果也一样。 我也增加了等待时间,但结果相同。 使其工作的唯一方法是使用Thread.sleep()(上面评论) 编辑请注意,我没有看到任何重复与

  • 运行Laravel 6.20.7。我的关系很直接。在我的类上定义: 我可以直接访问关系“线”,如下所示: 这将按预期输出集合: 我想急切地加载关系,将这些“行”整齐地传递到我的视图中,并带有每个“头”。我是这样问的: 但是,快速DD会显示一个空的关系集合。 值得一提的是,我尝试在模型上定义关系的逆关系,但没有成功。

  • 问题内容: 您可以将int隐式转换为double: 您可以将int显式转换为double: 您可以将double显式转换为int: 为什么不能将一个double隐式转换为int? : 问题答案: 的范围比宽。这就是为什么您需要显式强制转换。由于相同的原因,您不能隐式地从转换为:

  • 在示例代码中 在这个页面上, lock1和lock2分别控制c1和c2上的更新。 然而, 正在获取对象lock1的锁并在同步块时释放它 被执行。 当这个代码块被执行时,这个对象的成员c1上可能还有一个更新——我看不出这个更新是如何被代码中的lock1上的同步所阻止的。 只有对象lock1可以独占访问——除此之外别无它物(?) 那么,实施情况如何 在上面的代码中不同于 甚至 当c1是一个对象而不是一

  • 问题内容: 输出是 线程1开始 线程1的内部演示 线程2开始 线程2的内部演示 由于,执行尚未结束。 我已经通过类的同一个实例来的两个类的构造函数和。 对in 的调用位于一个块中。 要在通话中是 没有 的块。 所以,当被执行时,由于块,的监视器应锁定,导致拒绝访问,以由所述。 但是,这没有发生。 预期的输出是 (输出在完成之前。) 因此,我的基本问题是: 即使 尚未完成 块, 如何成功执行? 问题