剖析java.util.concurrent锁

1. 导言

程序的性能分析是应用程序开发过程中的一个重要方面。这个工作一般是由一些专业人员来完成的,他们的目标是在一个特定的平台上,提高代码的性能。当程序是运行在多核平台的多线程或者并行程序的时候,提高性能这个问题就变得更加困难了。因为在这样的情况下,不仅需要考虑代码的性能,还需要考虑代码的可伸缩性。

随着Java 5中引入了java.util.concurrent (JUC)包,在Java语言中出现了一种新的锁。JUC包使用得越来越普遍,因为更多的应用程序需要为了多核系统而开发或仔细地调优。虽然JLM可以找到传统的Java锁的详细的竞争信息,但是却没有同样的工具能够找到java.util.concurrent.locks包的锁竞争信息。 Sun/Oracle、IBM,还有其他Java厂商也都没有这样的工具。缺乏对JUC锁的剖析工具正是我们开发这个锁工具,jucprofiler(Multicore SDK的一部分)的动机。

2. jucprofiler概览

当在程序中使用JUC锁的时候,线程会在下面两种情况下“停止”执行:

当线程A试图去获得一个JUC锁,但这个锁却已经被另外一个线程获得,那么线程A不得不“停止”,直到这个锁被释放或者超时。

当线程A调用了java.util.concurrent.locks.Condition的任意一个“等待”的API,线程A会停止执行,直到另外一个线程通知它或者超时。

我们分别把这两种情况称作“锁竞争时间”和“等待时间”。

jucprofiler就是为了捕获以上两种情况的时间开销而设计和实现的。

2.1. 代码修改(Instruments)

为了获取JUC锁的运行时数据,需要提前修改一些JUC类,然后替换掉JRE中相应的类。在首次使用jucprofiler之前,用户需要运行命令去生成PreInstrument.jar。假设JRE没有改变的话,这个步骤只需要做一次。(如果用户改变了JRE,那么用户需要自己删除 PreInstrument.jar,然后重新运行这个命令,来再次生成PreInstrument.jar)。


2.1.1. 锁竞争时间开销

对于锁竞争时间开销,jucprofiler记录了申请类 java.util.concurrent.locks.AbstractQueuedSynchronizer 和类java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject的实例,并且给这些实例分配唯一的标识。

方法 调用位置
java.util.concurrent.locks.LockSupport park (Object); 类AbstractQueuedSynchronizer中的方法parkAndCheckInterrupt()
  parkNanos(Object blocker, long nanos) 类AbstractQueuedSynchronizer中的方法doAcquireNanos(int arg, long nanosTimeout)与doAcquireSharedNanos(int arg, long nanosTimeout)

2.1.2. 锁等待时间开销

对于锁等待时间开销,jucprofiler获取了在不同的位置调用类java.util.concurrent.locks.LockSupport的方法park(blocker)与parkNanos(blocker, nanos)的时间开销:

方法 调用位置
java.util.concurrent.locks.LockSupport park (Object); 类 AbstractQueuedSynchronizer除parkAndCheckInterrupt()以外的方法
  parkNanos(Object blocker, long nanos) 类AbstractQueuedSynchronizer除doAcquireNanos(int arg, long nanosTimeout)与doAcquireSharedNanos(int arg, long nanosTimeout) 以外的方法
时间: 2024-09-20 11:05:41

剖析java.util.concurrent锁的相关文章

java.util.concurrent包源码阅读(二) java.util.concurrent.atomic包

Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的AomicStampedReferrence,它不是AomicReferrence的子类,而是利用AomicReferrence实现的一个储存引用和Integer组的扩展类 首先,所有原子操作都是依赖于sun.misc.Unsafe这个类,这个类底层是由C++实现的,利用指针来实现数据操作 关于CAS

java.util.concurrent包源码阅读(一) 源码包的结构

准备花点时间阅读一下java.util.concurrent这个包里面的java代码,大致看了一下,这个包我个人觉得大致可以分为五个部分(如有不对之处,还望指正) 第一部分 Aomic数据类型 这部分都被放在java.util.concurrent.atomic这个包里面,实现了原子化操作的数据类型,包括 Boolean, Integer, Long, 和Referrence这四种类型以及这四种类型的数组类型. 第二部分 锁 这部分都被放在java.util.concurrent.lock这个包

关于java.util.concurrent您不知道的5件事,第2部分

并发 Collections 提供了线程安全.经过良好调优的数据结构,简化了并发编程.然而, 在一些情形下,开发人员需要更进一步,思考如何调节和/或限制线程执行.由于 java.util.concurrent 的总体目标是简化多线程编程,您可能希望该包包含同步实用程序,而 它确实包含. 本文是 第 1 部分 的延续,将介绍几个比核心语言原语(监视器)更高级的同步结构,但 它们还未包含在 Collection 类中.一旦您了解了这些锁和门的用途,使用它们将非常直观. 1. Semaphore 在一

java.util.concurrent解析——AbstractQueuedSynchronizer综述

尽管JVM在并发上已经做了很多优化工作,如偏向锁.轻量级锁.自旋锁等等.但是基于Synchronized wait notify实现的同步机制还是无法满足日常开发中.原生同步机制在时间和空间上的开销也一直备受诟病.为了提升Java程序在并发场景下的性能.扩展性和健壮性,java.util.concurrent的使用必不可少.java.util.concurrent 包含许多线程安全.测试良好.高性能的并发构建块.通过使用java.util.concurrent,开发人员可以提高并发类的线程安全.

java.util.concurrent.locks.LockSupport

要学习JAVA中是如何实现线程间的锁,就得从LockSupport这个类先说起,因为这个类实现了底层的一些方法,各种的锁实现都是这个基础上发展而来的.这个类方法很少,但理解起来需要花费一点时间,因为涉及了很多底层的知识,这些都是我们平时不关心的. 上源代码: package java.util.concurrent.locks; import java.util.concurrent.*; import sun.misc.Unsafe; public class LockSupport { pr

java.util.concurrent包(1)——lock和synchronized对比

一.对synchronized的改进 JDK5后引入了线程并发库java.util.concurrent.JSR 166小组花了这么多时间来开发java.util.concurrent.lock框架呢?答案很简单--synchronized同步是不错,但它并不完美,有一些功能性的限制:无法中断一个正在等候获得锁的线程,也无法通过投票得到锁,如果不想等下去也就没法得到锁.同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行,多数情况下这没问题,而且与异常处理交互得很好,但确实存在一些非块

为什么java.util.concurrent 包里没有并发的ArrayList实现?

原文链接 作者:Stephen C 译者:郑旭东  校对:方腾飞 问:JDK 5在java.util.concurrent里引入了ConcurrentHashMap,在需要支持高并发的场景,我们可以使用它代替HashMap.但是为什么没有ArrayList的并发实现呢?难道在多线程场景下我们只有Vector这一种线程安全的数组实现可以选择么?为什么在java.util.concurrent 没有一个类可以代替Vector呢? 答:我认为在java.util.concurrent包中没有加入并发的

Java 并发工具包 java.util.concurrent 用户指南

译序 本指南根据 Jakob Jenkov 最新博客翻译,请随时关注博客更新:http://tutorials.jenkov.com/java-util-concurrent/index.html. 本指南已做成中英文对照阅读版的 pdf 文档,有兴趣的朋友可以去 Java并发工具包java.util.concurrent用户指南中英文对照阅读版.pdf[带书签] 进行下载. 1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平

【JAVA秒会技术之多线程】Java 并发工具包 java.util.concurrent 用户指南

1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Java 的并发编程变得更加简单轻松的类.在这个包被添加以前,你需要自己去动手实现自己的相关工具类.本文我将带你一一认识 java.util.concurrent 包里的这些类,然后你可以尝试着如何在项目中使用它们.本文中我将使用 Java 6 版本,我不确定这和 Java 5 版本里的是否有一些差异.