在Java每个对象有一个同步监测。所以我想实施的是漂亮的凝聚在一词的存储器的使用和希望的快。

当移植这C++什么怎样以最佳的执行。我认为,必须有更好的东西然后"pthread_mutex_init"或是目的开销在java真的那么高?

编辑:我只是检查,pthread_mutex_t在Linux上i386是24字节大。这就是巨大的,如果我必须保留这一空间的每个物体。

有帮助吗?

解决方案

太阳热点JVM器具锁使用的比较和交换 。如果一个对象被锁定,则等待线程等待线程的监视器,锁定的对象。这意味着你只需要每个线程一个沉重的锁。

其他提示

在某种意义上,它比pthread_mutex_init差,其实。由于Java的等待/通知你那种需要配对互斥和条件变量来实现监控。

在实践中,实现JVM你追捕并在书中所适用的每一个特定于平台的优化,再创造一些新的,使显示器尽可能快的时候。如果你不能做一个真正的魔王工作,你肯定达不到优化垃圾收集; - )

一个观察结果是,并非每一个对象都需要有其自己的显示器。当前没有同步的对象并不需要一个。因此,JVM可以创建监控池,每个对象可能只是有一个指针场,这是当一个线程实际上想要在对象上同步填充(带有特定于平台的原子的比较和交换操作,例如)。因此,显示器初始化成本没有添加到创建对象的成本。假设存储器被预澄清,对象创建可以是:递减一个指针(加上某种边界的检查,与预测的假分支到运行GC等的代码);填写的类型;调用最派生构造函数。我想你可以安排对象的构造函数什么也不做,但很明显,在很大程度上取决于执行。

在实践中,平均的Java应用程序是不是在任何一个时间上同步很许多对象,所以显示器池是潜在地时间和存储器的巨大优化。

我不知道该如何Java不,但.净不互斥(或模拟的结构持有,它被称为"syncblk"有)直接的对象。相反,它具有全球表的syncblks,并对象引用其syncblk的指数在于表。此外,对象没有得到一个syncblk,尽快为他们创建的,相反,它是建立在需求上的第一个锁。

我假定(注意,我不知道它是如何实际上不!) 它使用原子比较和交换关联对象及其syncblk在线安全的方式:

  1. 检查隐藏的 syncblk_index 领域,我们的对象为0.如果它不0,它锁和继续,否则...
  2. 创建一个新的syncblk在全球表格,得到的指数为它(全球锁的获取/释放这里需要)。
  3. 比较和交流来编写它成为目的本身。
  4. 如果以前的价值为0(假设0不是一个有效指标,并是最初价值为隐藏的 syncblk_index 领域,我们的对象),我们syncblk创作是没有争议。锁定它,并继续进行。
  5. 如果以前的价值是不0,然后别人已经创建了一个syncblk和关联对象的同时,我们被创造我们,我们有索引的,syncblk。处理一个我们刚刚创建,并锁定在一个我们已经获得的。

因此开销逐对象是4个字节(假定的32位的指数进syncblk表)在最好情况,但更大的对象,这实际上已经锁定。如果你只有很少锁定你的对象,那么这个方案看起来像一个好的方法来减少资源使用情况。但如果你需要锁上大多数或所有对象的最终储存的互斥的对象可能更快。

当然,你并不需要这样的监视器的每一个的对象!

当从Java移植到C ++,它给我的印象是一个坏主意,只是复制一切盲目。 Java的最佳结构是不一样的最好的C ++,这不仅是因为Java有垃圾收集和C ++不。

显示器添加到只有那些真正需要它的对象。如果一个类型的仅某些情况下需要同步那么它是不是很难创建一个包含必要的同步互斥(以及可能的条件变量)的包装类。正如其他人已经说过的,一个替代方案是使用同步对象的池与选择一个为每个对象,例如使用对象地址的哈希索引数组的一些手段。

我会使用升压线程库或用于便携新的C ++ 0x标准线程库,而不是在每次转动依靠平台的细节。 Boost.Thread 支持Linux,MacOSX上的Win32,Solaris和HP-UX和其他。我实施目前仅支持Windows和Linux的C ++ 0x线程库的,但其他的实现将成为在适当的时候提供。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top