以前的文章就简单的给你们介绍了各类锁的介绍与使用(文末有对应的连接),目前这章为以后讲解锁的操做底层实现先奠基下基础。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