JavaCAS深入理解(牛篇)

鼠篇写的基本都是理论基础,最近在研究Unsafe的源码,大致看了看,还没有太深入这篇牛篇,只能算是做个资源记录吧。

从AtomicInteger类源码看起来。

AtomicInteger源码部分:

// setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;

这里比较神奇的是:unsafe.objectFieldOffset 这个方法,方法的参数是Field类型。这里就是声明的volatile类型的value属性。

跟踪到Hotspot源码里可以看到:

Unsafe.cpp

UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field))
  UnsafeWrapper("Unsafe_ObjectFieldOffset");
  return find_field_offset(field, 0, THREAD);
UNSAFE_END
jint find_field_offset(jobject field, int must_be_static, TRAPS) {
  if (field == NULL) {
    THROW_0(vmSymbols::java_lang_NullPointerException());
  }

  oop reflected   = JNIHandles::resolve_non_null(field);
  oop mirror      = java_lang_reflect_Field::clazz(reflected);
  klassOop k      = java_lang_Class::as_klassOop(mirror);
  int slot        = java_lang_reflect_Field::slot(reflected);
  int modifiers   = java_lang_reflect_Field::modifiers(reflected);

  if (must_be_static >= 0) {
    int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0);
    if (must_be_static != really_is_static) {
      THROW_0(vmSymbols::java_lang_IllegalArgumentException());
    }
  }

  int offset = instanceKlass::cast(k)->offset_from_fields(slot);
  return field_offset_from_byte_offset(offset);
}

想看懂这段代码,必须看懂java在jvm里的对象体系了。

这篇文章很不错,对此做了一个大概况介绍  http://www.sczyh30.com/posts/Java/jvm-klass-oop/

时间: 2024-10-13 17:38:53

JavaCAS深入理解(牛篇)的相关文章

简单理解算法篇--摊还分析

摊还分析是用来评价程序中的一个操作序列的平均代价,有时可能某个操作的代价特别高,但总体上来看也并非那么糟糕,可以形象的理解为把高代价的操作“分摊”到其他操作上去了,要求的就是均匀分摊后的平均代价. 摊还分析有三种常用的技术:聚合分析,核算法,势能法. 首先看个例子,现在有三种操作,push(s),pop(s),mutlipop(s,k),push(s),统称为栈操作. push(s)每次只能压一个数据,所以规定操作的代价为1,pop(s)每次只能弹一个数据,所以也规定操作的代价为1,而mutli

作用域的理解--第一篇

浏览器: “JS解析器” 1)JS 的预解析   “找一些东西” :var function 参数 a = ... 所有的变量,在正式运行代码之前,都提前赋了一个值:未定义 fn1 = function fn1(){ alert(2); } 所有的函数,在正式运行代码之前,都是整个函数块 遇到重名的:只留一个 变量和函数重名了,就只留下函数 相同的函数名的话, 后面会覆盖前面的函数 2)逐行解读代码: 表达式:= + - * / % ++ -- ! 参数…… 表达式可以修改预解析的值! 注意:

简单理解算法篇--动态规划

动态规划方法通常用来求解最优化问题,这些问题有很多种解,但我们希望寻求最优解. 满足两个条件既可以使用动态规划 1.具有最优子结构 2.子问题重叠 至于这两点是什么意思?先看个问题 现在有个钢筋长度和价格对应的表,问:给你个长度为n的钢筋怎么卖最划算? 长度 1 2 3 4  5   6  7   8   9  10 价格 1 5 8 9 10 17 17 20 24 30 现在就是要把所有的切法都遍历一遍,找出最划算的切法,当你把钢筋切了一刀后,是不是变成了两段?那就要考虑的就是这两段怎么切最

浏览器渲染 理解终结篇

简单言之,浏览器的渲染和操作顺序如下: html解析完毕 外部脚本和样式表加载完毕 脚本在文档内解析并执行 html dom完全构造起来 涂攀和外部内容加载 对于外部js文件来说,先加载外部js文件,然后执行js代码,DOM加载并不能保证在其执行前加载完毕. 而行内js,由于按照顺序执行,在js代码执行时,位于行内js之前的元素,其对应的dom节点都可以建立起来.比如 <ul> <li><a href="javascript:;" class="

android5.0(Lollipop) BLE Peripheral深入理解系统篇之提高篇

上一篇文章讲到了广播之前系统需要进行的准备工作,那接下来我们就来真正的启动广播. 首先还是先看一下上一篇文章结束的地方: @Override public void onClientRegistered(int status, int clientIf) { Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf); synchronized (this) { if

简单理解算法篇--贪心算法

贪心算法是什么意思?举个例子就很清楚了:现在你有一个能装4斤苹果的袋子,苹果有两种,一种3斤一个,一种2斤一个,怎么装才能得到最多苹果?当然我们人考虑的话当然是拿两个2斤的苹果,就刚好装满了,但是如果按贪心算法拿的话,首先就要把最重的苹果拿下(是不是很符合贪心两个字?),但并没有得到最多苹果. 贪心算法保证了局部最优,但并不能保证得到最优解. 什么时候用贪心法?满足下面两个条件 1.       具有最优子结构 2.       贪心选择性 第1点跟动态规划的条件一样,其实贪心跟动态规划一样,都

AngularJs入门篇-控制器的加深理解基础篇

下面做的是一个更新时间的效果,每一秒钟就会更新一下,视图中会显示出当前的时间   下面的这个例子中,SceondController函数将接受两个参数,既该DOM元素的$scope和$timeout. 可以将视图中clock变量用{{}}包起来,以显示$scope中的clock的值. ///////////////  THML <div ng-controller="SceondController"> <h5>{{ clock }}</h5> &l

游戏开发不完全理解 -- 建模篇

<上古卷轴4>中的SpeedTree渲染出的草地效果 当然,SpeedTree也不只是应用在游戏领域,SpeedTree也是商业上常用的建模工具,更有美国国防部利用SpeedTree进行真实战争场景模拟来进行军事训练. 原文地址:https://www.cnblogs.com/yc8930143/p/10663875.html

使用WebRTC搭建前端视频聊天室——数据通道篇

转自 使用WebRTC搭建前端视频聊天室——数据通道篇 在两个浏览器中,为聊天.游戏.或是文件传输等需求发送信息是十分复杂的.通常情况下,我们需要建立一台服务器来转发数据,当然规模比较大的情况下,会扩展成多个数据中心.这种情况下很容易出现很高的延迟,同时难以保证数据的私密性. 这些问题可以通过WebRTC提供的RTCDataChannel API来解决,他能直接在点对点之间传输数据.这篇文章将介绍如何创建并使用数据通道,并提供了一些网络上常见的用例 为了充分理解这篇文章,你可能需要去了解一些RT