什么是C++中最有效的类Java对象监视器实现?[关闭]

i5desfxk  于 2023-11-19  发布在  Java
关注(0)|答案(4)|浏览(111)

已关闭。此问题需要更多focused。目前不接受回答。
**要改进此问题吗?**更新此问题,使其仅针对editing this post的一个问题。

10天前关闭。
Improve this question
在Java中,每个对象都有一个同步监视器。所以我想这个实现在内存使用方面是相当精简的,希望也很快。
当把它移植到C++的时候,什么是最好的实现呢?我认为一定有比“pthread_mutex_init”更好的东西,或者java中的对象开销真的这么高吗?
编辑:我刚刚检查了Linux i386上的pthread_mutex_t是24字节大。如果我必须为每个对象保留这个空间,那就太大了。

zour9fqk

zour9fqk1#

实际上,在某种意义上,它比pthread_mutex_init更糟糕,因为Java的wait/notify,你需要一个成对的互斥体和条件变量来实现一个监视器。
在实践中,当你实现一个JVM的时候,你会寻找并应用书中提到的每一个平台特定的优化,然后发明一些新的优化,使监视器尽可能快。如果你不能做一个真正可怕的工作,你肯定不能优化垃圾收集;-)
一个观察结果是,不是每个对象都需要有自己的监视器。当前未同步的对象不需要监视器。因此JVM可以创建一个监视器池,每个对象可以只有一个指针字段,当线程实际上希望在对象上同步时,该字段将被填充(例如,使用特定于平台的原子比较和交换操作)。因此,监视器初始化的成本不必增加对象创建的成本。假设内存被预先清除,对象创建可以是:递减一个指针(加上某种边界检查,带有一个运行gc的代码的predicted-false分支,等等);填充类型;调用最派生的构造函数。我认为你可以安排Object的构造函数什么也不做,但很明显,这在很大程度上取决于实现。
在实践中,一般的Java应用程序在任何时候都不会同步很多对象,因此监视器池可能是时间和内存方面的巨大优化。

fslejnso

fslejnso2#

The Sun Hotspot JVM implements thin locks using compare and swap。如果一个对象被锁定,那么等待线程会在锁定该对象的线程的监视器上等待。这意味着每个线程只需要一个重锁。

yjghlzjz

yjghlzjz3#

我不确定Java是如何做到的,但是.NET并没有直接在对象中保存互斥锁(或者类似的--保存它的结构被称为“syncblk”)。相反,它有一个全局的syncblk表,对象通过该表中的索引引用它的syncblk。此外,对象不会在创建后立即获得syncblk--相反,它是在第一个锁上按需创建的。
我假设(注意,我不知道它实际上是如何做到的!)它使用原子比较和交换来以线程安全的方式关联对象和它的syncblk:
1.检查我们对象的隐藏syncblk_index字段是否为0。如果不是0,锁定它并继续,否则.
1.在全局表中创建一个新的syncblk,获取它的索引(根据需要在这里获取/释放全局锁)。
1.比较和交换将其写入对象本身。
1.如果前一个值为0(假设0不是一个有效的索引,并且是我们对象的隐藏syncblk_index字段的初始值),则我们的syncblk创建没有被争用。锁定它并继续。
1.如果前一个值不为0,那么在我们创建对象的时候,其他人已经创建了一个syncblk并将其与对象关联起来,现在我们有了那个syncblk的索引。
因此,在最好的情况下,每个对象的开销是4个字节(假设syncblk表中的索引为32位),但是对于实际上已经锁定的对象来说,开销会更大。如果你很少锁定对象,那么这个方案看起来是一个减少资源使用的好方法。但是如果你最终需要锁定大多数或所有对象,直接在对象中存储互斥量可能会更快。

fafcakar

fafcakar4#

当然,你不需要这样一个监视器为 * 每 * 对象!
当从Java移植到C时,盲目地复制所有东西对我来说是一个坏主意。Java的最佳结构与C的最佳结构是不一样的,尤其是因为Java有垃圾收集,而C没有。
只给那些真正需要监视器的对象添加监视器。如果只有一个类型的一些示例需要同步,那么创建一个包含互斥体的 Package 器类并不难正如其他人已经说过的,一种替代方案是使用同步对象池,其中具有为每个对象选择一个同步对象的某种手段,例如使用对象地址的散列来索引数组。
我会使用boost线程库或新的C
0x标准线程库来实现可移植性,而不是依赖于每个回合的平台细节。Boost.Thread支持Linux、MacOSX、win32、Solaris、HP-UX和其他。我的implementation of the C++0x thread library目前只支持Windows和Linux,但其他实现将在适当的时候提供。

相关问题