文章目录
说明:JVM并没有规定Synchronized应该怎么实现,这里说的是基于HotSpot的实现
用户态与内核态
JDK早期,synchronized 叫做重量级锁, 因为申请锁资源必须通过kernel, 系统调用
;hello.asm
;write(int fd, const void *buffer, size_t nbytes)
section data
msg db "Hello", 0xA
len equ $ - msg
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1 ;文件描述符1 std_out
mov eax, 4 ;write函数系统调用号 4
int 0x80
mov ebx, 0
mov eax, 1 ;exit函数系统调用号
int 0x80
CAS
-
-
Compare And Swap(Set) (Compare And Exchange)又被称为: 自旋 / 自旋锁 / 无锁 (无重量锁)
-
因为经常配合循环操作,直到完成为止,所以泛指一类操作
-
cas(V, Expected, NewValue) ,变量V,期待值Expected, 修改值NewValue if (v == a){ v = b } else{ try again or fail }
-
-
CAS操作得到了CPU的原语支持,也就是说CAS操作是CPU指令级别的操作,它中途是不可能被打断的
-
ABA问题,也就是原来a=1,之后有一个线程把它改成了 a=2,之后又把它改回成1;对于int类型肯定对结果无伤大雅,但是有一些数据结构不行,比如说对象,这可能会导致错误的结果,
解决办法:加一个版本号 (AtomicStampedReference),在这个对象做任何修改之前就改一下它的版本号,在if判断的时候连同版本号一起检查,比如版本好递增1。当然基础类型简单值不需要版本号,因为它们对结果没有影响。有影响就加一个版本号
-
CAS操作根本没有用到锁,就完成了锁的功能,但是它付出的代价就是占用CPU的资源,所以在原子类,轻量级锁等地方用到的都是CAS操作
Unsafe与原子类
-
所有的原子类的操作都是使用的Unsafe中的CompareAndSwap方法,这个方法的原理就是上面所说的CAS操作的原理,而这个方法是Unsafe这个类里面的。所以原子类的底层原理就是CAS
-
unsafe类是用来直接操作JVM里面的内存。比如要修改一个对象的属性,是直接通过偏移量在找到这块内存,直接修改。再比如我们可以调用Unsafe类的allocateMemory来分配指定大小的内存,之前的java可是没有这个功能的。这个只有在c,c++里面有
-
这个类了解就好,它里面又很多的方法,在JDK8之前,我们这些普通的用户是不能直接使用这个类,这个类是给那些JDK的作者来使用,我们必须通过反射来使用。但在之后的版本,Unsafe类提供了懒汉式的单例,使得我们可以直接拿到它。
AtomicInteger:
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
Unsafe:
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
运用:
package com.mashibing.jol;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class T02_TestUnsafe {
int i = 0;
private static T02_TestUnsafe t = new T02_TestUnsafe();
public static void main(String[] args) throws Exception {
//Unsafe unsafe = Unsafe.getUnsafe();
Field unsafeField = Unsafe.class.getDeclaredFields()[0];
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.