以前的文章就簡單的給你們介紹了各類鎖的介紹與使用(文末有對應的連接),目前這章爲以後講解鎖的操做底層實現先奠基下基礎。java
JAVA
中基本類型的轉換是不涉及操做數的,轉換的值是直接從棧頂端得到,JAVA
虛擬機從棧頂彈出一個值,對他進行轉換,而後再把轉換結果壓入棧中。多線程
操做碼 | 操做數 | 備註 |
---|---|---|
i2l | 無 | 將int類型的值轉換爲long類類型 |
i2f | 無 | 將int類型的值轉換爲float類類型 |
i2d | 無 | 將int類型的值轉換爲double類類型 |
l2i | 無 | 將long類型的值轉換爲int類類型 |
l2f | 無 | 將long類型的值轉換爲float類類型 |
l2d | 無 | 將long類型的值轉換爲double類類型 |
f2i | 無 | 將float類型的值轉換爲int類類型 |
f2l | 無 | 將float類型的值轉換爲long類類型 |
f2d | 無 | 將float類型的值轉換爲double類類型 |
d2i | 無 | 將double類型的值轉換爲int類類型 |
d2l | 無 | 將double類型的值轉換爲long類類型 |
d2f | 無 | 將double類型的值轉換爲float類類型 |
操做碼 | 操做數 | 備註 |
---|---|---|
i2b | 無 | 將int類型的值轉換爲byte類型值,進行帶符號擴展,恢復爲int類型壓入棧 |
i2c | 無 | 將int類型的值轉換爲char類型值,進行零擴展,恢復成int類型壓入棧 |
i2s | 無 | 將int類型的值轉換爲short類型值,進行帶符號擴展,恢復成int類型壓入棧 |
不存在比
int
類型佔據更小空間的數據類型轉化爲int
類型操做碼。由於上面三種才進行壓入棧的時候,就已經轉換爲int
類型,而後再對int
類型值進行運算,最後獲得int
類型值。併發
Demo:ide
public static void main(String[] args) {
byte a =2;
byte b =1;
byte c = (byte) (a+b);
}
複製代碼
public static void main(java.lang.String[]);
Code:
0: iconst_2 //常量2入棧
1: istore_1 //彈出棧頂元素存入位置1的局部變量
2: iconst_1
3: istore_2
4: iload_1 //取出位置1的局部變量值入棧
5: iload_2
6: iadd //加法運算
7: i2b //int類型轉化爲byte類型值
8: istore_3 //彈出棧頂元素存入位置3的局部變量
9: return
}
複製代碼
操做碼 | 操做數 | 備註 |
---|---|---|
iconst_m1 | 無 | 將int類型值-1壓入棧 |
iconst_0 | 無 | 將int類型值0壓入棧 |
iconst_1 | 無 | 將int類型值1壓入棧 |
iconst_2 | 無 | 將int類型值2壓入棧 |
iconst_3 | 無 | 將int類型值3壓入棧 |
fconst_0 | 無 | 將float類型值0壓入棧 |
fconst_1 | 無 | 將float類型值1壓入棧 |
fconst_2 | 無 | 將float類型值2壓入棧 |
lconst_0 | 無 | 將long類型值0壓入棧 |
lconst_1 | 無 | 將long類型值1壓入棧 |
dconst_0 | 無 | 將double類型值0壓入棧 |
dconst_1 | 無 | 將double類型值1壓入棧 |
aconst_null | 無 | 將空(null)對象壓入棧 |
操做碼 | 操做數 | 備註 |
---|---|---|
bipush | 一個byte類型的數 | 將byte類型的數轉換爲int類型的數,而後壓入棧 |
sipush | 一個short類型的數 | 將short類型的數轉換爲int類型的數,而後壓入棧 |
操做碼 | 操做數 | 備註 |
---|---|---|
ldc | 無符號8位數indexbyte | 從由indexbyte指向的常量池入口中取出一個字長的值,而後將其壓入棧 |
ldc_w | 無符號16位數indexshort | 從由indexbyte指向的常量池入口中取出兩個字長的值,而後將其壓入棧 |
操做碼 | 操做數 | 備註 | Demo |
---|---|---|---|
nop | 無 | 不作任何操做 | 前:...,word 後:...,word,word |
pop | 無 | 從操做數棧彈出棧頂部一個字 | 前:...,word 後:... |
pop2 | 無 | 從棧頂數彈出最頂端的兩個字 | |
swap | 無 | 交換棧頂部的兩個字 | 前:...,word2,word1 後:...,word1,word2 |
dup | 無 | 複製棧頂部的一個字 | |
dup2 | 無 | 複製棧頂部的兩個字 | |
dup2 | 無 | 複製棧頂部的兩個字 | |
dup_x1 | 無 | 複製棧頂部的一個字, 將複製內容以及原來彈出的兩 個字長的內容壓入棧 |
前:...,word2,word1 後:...,word1,word2,word1 |
dup_x2 | 無 | 複製棧頂部的一個字, 將複製內容以及原來彈出的三 個字長的內容壓入棧 |
前:.,word3,word2,word1 後:.,word1,word3,word2,word1 |
dup2_x1 | 無 | 複製棧頂部的兩個字, 將複製內容以及原來彈出的三 個字長的內容壓入棧 |
|
dup2_x2 | 無 | 複製棧頂部的兩個字, 將複製內容以及原來彈出的四 個字長的內容壓入棧 |
操做碼 | 操做數 | 備註 |
---|---|---|
iload | vindex | 將位置爲vindex的int類型的局部變量壓入棧 |
iload_0 | 無 | 將位置爲0的int類型的局部變量壓入棧 |
iload_1 | 無 | 將位置爲1的int類型的局部變量壓入棧 |
iload_2 | 無 | 將位置爲2的int類型的局部變量壓入棧 |
iload_3 | 無 | 將位置爲3的int類型的局部變量壓入棧 |
fload | vindex | 將位置爲vindex的float類型的局部變量壓入棧 |
fload_0 | 無 | 將位置爲0的float類型的局部變量壓入棧 |
fload_1 | 無 | 將位置爲1的float類型的局部變量壓入棧 |
fload_2 | 無 | 將位置爲2的float類型的局部變量壓入棧 |
fload_3 | 無 | 將位置爲3的float類型的局部變量壓入棧 |
操做碼 | 操做數 | 備註 |
---|---|---|
lload | vindex | 將位置爲vindex和(vindex+1)的long類型的局部變量壓入棧 |
lload_0 | 無 | 將位置爲0和1的long類型的局部變量壓入棧 |
lload_1 | 無 | 將位置爲1和2的long類型的局部變量壓入棧 |
lload_2 | 無 | 將位置爲2和3的long類型的局部變量壓入棧 |
lload_3 | 無 | 將位置爲3和4的long類型的局部變量壓入棧 |
dload | vindex | 將位置爲vindex和(vindex+1)的double類型的局部變量壓入棧 |
dload_0 | 無 | 將位置爲0和1的double類型的局部變量壓入棧 |
dload_1 | 無 | 將位置爲1和2的double類型的局部變量壓入棧 |
dload_2 | 無 | 將位置爲2和3的double類型的局部變量壓入棧 |
dload_3 | 無 | 將位置爲3和4的double類型的局部變量壓入棧 |
操做碼 | 操做數 | 備註 |
---|---|---|
aload | vindex | 將位置爲vindex的對象引用局部變量壓入棧 |
aload_0 | 無 | 將位置爲0的對象引用局部變量壓入棧 |
aload_1 | 無 | 將位置爲1的對象引用局部變量壓入棧 |
aload_2 | 無 | 將位置爲2的對象引用局部變量壓入棧 |
aload_3 | 無 | 將位置爲3的對象引用局部變量壓入棧 |
移動一個字長的操做:post
操做碼 | 操做數 | 備註 |
---|---|---|
istore | vindex | 從棧中彈出int類型值,而後存到位置爲vindex的局部變量中 |
istore_0 | 無 | 從棧中彈出int類型值,而後存到位置爲0的局部變量中 |
istore_1 | 無 | 從棧中彈出int類型值,而後存到位置爲1的局部變量中 |
istore_2 | 無 | 從棧中彈出int類型值,而後存到位置爲2的局部變量中 |
istore_3 | 無 | 從棧中彈出int類型值,而後存到位置爲3的局部變量中 |
fstore | vindex | 從棧中彈出float類型值,而後存到位置爲vindex的局部變量中 |
fstore_0 | 無 | 從棧中彈出float類型值,而後存到位置爲0的局部變量中 |
fstore_1 | 無 | 從棧中彈出float類型值,而後存到位置爲1的局部變量中 |
fstore_2 | 無 | 從棧中彈出float類型值,而後存到位置爲2的局部變量中 |
fstore_3 | 無 | 從棧中彈出float類型值,而後存到位置爲3的局部變量中 |
移動兩個字長的操做:spa
操做碼 | 操做數 | 備註 |
---|---|---|
lstore | vindex | 從棧中彈出long類型值,而後存到位置爲vindex和(vindex+1)的局部變量中 |
lstore_0 | 無 | 從棧中彈出long類型值,而後存到位置爲0和1的局部變量中 |
lstore_1 | 無 | 從棧中彈出long類型值,而後存到位置爲1和2的局部變量中 |
lstore_2 | 無 | 從棧中彈出long類型值,而後存到位置爲2和3的局部變量中 |
lstore_3 | 無 | 從棧中彈出long類型值,而後存到位置爲3和4的局部變量中 |
dstore | vindex | 從棧中彈出double類型值,而後存到位置爲vindex和(vindex+1)的局部變量中 |
dstore_0 | 無 | 從棧中彈出double類型值,而後存到位置爲0和1的局部變量中 |
dstore_1 | 無 | 從棧中彈出double類型值,而後存到位置爲1和2的局部變量中 |
dstore_2 | 無 | 從棧中彈出double類型值,而後存到位置爲2和3的局部變量中 |
dstore_3 | 無 | 從棧中彈出double類型值,而後存到位置爲3和4的局部變量中 |
移動引用的操做: 移動兩個字長的操做:線程
操做碼 | 操做數 | 備註 |
---|---|---|
astore | vindex | 從棧中彈出對象引用,而後存到位置爲vindex的局部變量中 |
astore_0 | 無 | 從棧中彈出對象引用,而後存到位置爲0的局部變量中 |
astore_1 | 無 | 從棧中彈出對象引用,而後存到位置爲1的局部變量中 |
astore_2 | 無 | 從棧中彈出對象引用,而後存到位置爲2的局部變量中 |
astore_3 | 無 | 從棧中彈出對象引用,而後存到位置爲3的局部變量中 |
無符號8位局部變量索引,把方法中局部變量數的限制在256如下。一條單獨的wide指令能夠將8位的索引再擴展8位。跳轉指令並不容許直接跳轉到被wide指令修改過的操做碼。3d
操做碼 | 操做數 | 備註 |
---|---|---|
wide | iload,index | 從局部變量位置爲index的地方取出int類型值,並將其壓入棧 |
wide | lload,index | 從局部變量位置爲index的地方取出long類型值,並將其壓入棧 |
wide | fload,index | 從局部變量位置爲index的地方取出float類型值,並將其壓入棧 |
wide | dload,index | 從局部變量位置爲index的地方取出double類型值,並將其壓入棧 |
wide | aload,index | 從局部變量位置爲index的地方取出對象引用,並將其壓入棧 |
wide | istore,index | 從棧中彈出int類型值,將其存入位置爲index的局部變量中 |
wide | lstore,index | 從棧中彈出long類型值,將其存入位置爲index的局部變量中 |
wide | lstore,index | 從棧中彈出long類型值,將其存入位置爲index的局部變量中 |
wide | fstore,index | 從棧中彈出float類型值,將其存入位置爲index的局部變量中 |
wide | dstore,index | 從棧中彈出double類型值,將其存入位置爲index的局部變量中 |
wide | astore,index | 從棧中彈出對象引用,將其存入位置爲index的局部變量中 |
以上先介紹一部分
JAVA
字節碼中的一些命令,接下來還有一些方法調用等等指令,下一篇文章給你們介紹下。code