实时Java,第3部分 - 线程化和同步 - 编程入门网
,分配了一个惟一的 pthread_mutex 并使用原子机器操作将其绑定到 Java 对象。对于 Java 级别的解锁操作,使用原子操作解除 pthread_mutex 与对象之间的绑定,前提是不存在锁争用。存在锁争用时,POSIX 锁定和解锁操作将触发 Linux 内核优先级继承支持。
为了帮助实现互斥锁分配和锁定时间的最小化,JVM 管理一个全局锁缓存和一个单线程锁缓存,其中每个缓存包含了未分配的 pthread_mutex。线程专用缓存中的互斥锁从全局锁缓存中获得。互斥锁在放入线程锁定缓存之前被线程预先锁定。非争用的解锁操作将一个锁定的互斥锁返回给线程锁定缓存。此处假定以非争用的锁定为标准,而 POSIX 级别的锁定则通过重用预先锁定的互斥锁来得到减少和摊销。 JVM 自身拥有内部锁,用于序列化对关键 JVM 资源(如线程列表和全局锁缓存)的访问。这些锁基于优先级继承并且其持有时间较短。 RT 应用程序的同步考虑 本节将介绍 RT 同步的一些特性,这些特性可以帮助移植应用程序的开发人员使用 RT 线程或编写新的应用程序以使用 RT 线程化。 普通 Java 线程和 RT 线程之间的锁争用 RT 线程可能被普通 Java 线程持有的锁阻塞。发生这种情况时,优先级继承接管线程,因此普通 Java 线程的优先级被提高到 RT 线程的优先级,并且只要它持有锁就一直保持该优先级。普通 Java 线程继承了 RT 线程的所有调度特征: 普通 Java 线程按 SCHED_FIFO 策略运行,因此线程不划分时间片。 在提高了优先级的 RT 运行队列中进行调度和让步。 此行为在普通 Java 线程释放锁时返回到 SCHED_OTHER。如果 清单 1 中创建的两个线程在持有 RT 线程所需要的锁的时候都不运行,则该程序将不会结束并且出现我们在 使用 RT 线程的问题代码示例 部分中描述的问题。因为可能出现这种情形,所以对于所有在实时 JVM 中执行的线程来说,执行 spin 循环和让步并不明智。 NHRT 和 RT 线程之间的锁争用 NHRT 可能在 RT 线程(或相应的普通 Java 线程)持有的锁处阻塞。虽然 RT 线程持有锁,但是 GC 可能抢占 RT 并间接地抢占 NHRT。NHRT 需要一直等到 RT 不再被 GC 抢占并释放锁后才能执行。如果 NHRT 执行的功能具有严格的时间要求,则 GC 抢占 NHRT 将是一个严重的问题。 WebSphere Real Time 中具有确定性的垃圾收集器将暂停时间保持在一毫秒以下,使 NHRT 抢占更具有确定性。如果不能容忍此类暂停,则可以通过避免 NHRT 和 RT 线程之间的锁共享来绕过该问题。如果强制使用锁定,则可以考虑使用特定于 RT 或 NHRT 的资源和锁。例如,实现线程入池的应用程序可以考虑对 NHRT 和 RT 线程使用分开的池和池锁。 同样,javax.realtime 包提供了以下的类: WaitFreeReadQueue 类主要用于将对象从 RT 线程传递到 NHRT。 WaitFreeWriteQueue 类主要用于将对象从 NHRT 传递到 RT 线程。 RT 线程在执行无等待操作时可能被 GC 阻塞,上述类保证了 RT 线程在执行无等待操作时不会持有 NHRT 所需的锁。 javax.realtime 包中的同步 某些 javax.realtime 方法故意没有实现同步,因为即使锁是无争用的,同步也会造成系统开销。如果需要同步,则调用方负责封装同步方法或块中所需的 javax.realtime 方法。编程人员在使用 java.realtime 包的方法时必须考虑添加此类同步。 核心 JLS 包中的同步 相反,如 java.util.Vector 之类的核心 JLS 服务已经实现同步。同样,某些核心 JLS 服务可以执行一些内部锁定来序列化某些共享资源。由于这种同步,在使用核心 JLS 服务时,必须谨慎执行以避免 GC 抢占 NHRT 的问题(参见 NHRT 和 RT 线程之间的锁争用)。 实时Java,第3部分 - 线程化和同步(11)时间:2011-06-22 Patrick Gallop Mark无争用锁定的性能 非 RT 应用程序的标准检查和检测已表明 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |