文章目錄
-
- 使用者态與核心态
- CAS 原理
- 對于一個新建立的對象,整個對象在記憶體中的布局
- 鎖的變化
linux作業系統體系架構分為使用者态和核心态,核心控制計算機的硬體資源,并提供上層應用程式的運作1環境,使用者态即上層應用程式的活動空間,應用程式必須依托于核心提供的資源,對于輕量級别的鎖,經過使用者态,不經過核心态,重量級别的鎖在一定程度上會經過核心态
CAS : Compare and Swap 即比較再交換
CAS是一種無鎖的算法,有3個操作數,記憶體值V,舊的預期值A,要修改的新值B,當且隻當預期值A和記憶體值V相同時,将記憶體值V修改為B,否則什麼都不做
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[100];
CountDownLatch latch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
a.incrementAndGet();
}
latch.countDown();
});
}
Arrays.stream(threads).forEach((t) -> t.start());
latch.await();
System.out.println(a);
}
其中a.incrementAndGet() 深入其中的源碼
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
調用了 getAndAddInt
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
compareAndSwapInt
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
對于java中的native關鍵字,凡是一種語言,都希望是純。比如解決某一個方案都喜歡就單單這個語言來寫即可。Java平台有個使用者和本地C代碼進行互操作的API,稱為Java Native Interface (Java本地接口)。
引入依賴
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
結果
在這裡插入代碼片
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
12 4 (loss due to the next object alignment)Instance size: 16 bytesSpace losses: 0 bytes internal + 4 bytes external = 4 bytes total
對于一個新建立的類,對64位的機器前8位為markword,後4位為class point 指定對象引用的類,由于沒有成員變量,是以隻有12位,故而往後補4位(loss due to the next object alignment),友善被8整除
将對象上鎖後的變化
synchronized (o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 38 f7 66 03 (00111000 11110111 01100110 00000011) (57079608)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
12 4 (loss due to the next object alignment)Instance size: 16 bytesSpace losses: 0 bytes internal + 4 bytes external = 4 bytes total