java源码学习(一)


AtomicBoolean源码分析

Java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,主要提供了以下功能:

1、通过Unsafe类可以分配内存,可以释放内存;
2、可以定位对象某字段的内存位置,也可以修改对象的字段值,即使它是私有的;
3、挂起与恢复
4、CAS操作:是通过compareAndSwapXXX方法实现的

详细内容请参考http://www.cnblogs.com/mickole/articles/3757278.html





unsafe.objectFieldOffset(AtomicBoolean.class.getDeclaredField("value"));
objectFieldOffset()方法用于获取某个字段相对Java对象的“起始地址”的偏移量

一个java对象可以看成是一段内存,各个字段都得按照一定的顺序放在这段内存里,同时考虑到对齐要求,可能这些字段不是连续放置的,用这个方法能准确地告诉你某个字段相对于对象的起始内存地址的字节偏移量,因为是相对偏移量,所以它其实跟某个具体对象又没什么太大关系,跟class的定义和虚拟机的内存模型的实现细节更相关。


unsafe.compareAndSwapInt比较obj的offset处内存位置中的值和期望的值,如果相同则更新。此更新是不可中断的

compareAndSet、weakCompareAndSet、getAndSet都是通过unsafe.compareAndSwapInt的方法来实现业务逻辑的!


lazySet方法 通过 unsafe.putOrderedInt(this, valueOffset, v) 方法实现
设置obj对象中offset偏移地址对应的整型field的值为指定值。这是一个有序或者有延迟的方法,并且不保证值的改变被其他线程立即看到。只有在field被修饰并且期望被意外修改的时候使用才有用。

AtomicInteger 源码分析




AtomicInteger 图上这些方法和AtomicBoolean的套路一样,主要不同的是下面这些方法:







AtomicInteger 的 getAndIncrement、getAndDecrement、getAndAdd、incrementAndGet、decrementAndGet、addAndGet 都是使用unsafe.getAndAddInt方法直接操作底层内存偏移地址对应的整型数值进行加减操作!

getAndAccumulate、accumulateAndGet、updateAndGet方法都是通过输入IntUnaryOperator接口类型的参数来实现逻辑的!这个类型是Java 8中新增加了一个包 java.util.function,带来了常用的 Lambda 表达式函数式接口,也就是箭头函数。这些方法都是jdk1.8以后开始提供的!



jdk1.8之后提供的方法:
getAndAccumulate(int x, IntBinaryOperator accumulatorFunction)自动更新当前值与给定的功能应用到当前和给定值的结果,返回前一个值。
accumulateAndGet(int x, IntBinaryOperator accumulatorFunction) 自动更新当前值与给定的功能应用到当前和给定值的结果,返回更新后的值。
updateAndGet(IntUnaryOperator updateFunction) 自动更新当前值与结果应用给定的函数,返回更新后的值。


Interface IntUnaryOperator
这是一个功能接口,因此可以作为赋值的目标一个lambda表达式或方法参考。
代表在一个单一的 int-valued操作数,产生一个 int-valued结果操作。这是 int的 UnaryOperator原始类型的专业化。
这是一个functional interface其功能的方法是applyAsInt(int)。




AtomicLong 和AtomicInteger所提供的方法差不多,大部分都是把方法返回的类型改成了Long,但是源码有一处代码引起了我的注意:





AtomicReference<V> 也不多说了 这四个基本类型懂一个另外三个也就明白了!


猜你喜欢

转载自zhaiwanpeng711.iteye.com/blog/2382656