前言
关于锁,这两个锁应该是面试最常见的内容;
上面两个大佬的文章,应该是看来看去写得比较清晰明白的了。
在回顾完这两个锁的实现,我又有一些新的疑问。
疑问
1.ReentrantLock的Node.SIGNAL这是什么东西,几种状态有什么意义
2.CAS面试要掌握到什么程度呢?
3.线程的中断?线程有哪些状态?
4.AQS和cas
5.操作系统线程是怎么切换的,内核态,用户态?
6.底层的操作系统的Mutex Lock?
7.i++操作细节,和++i的区别
另外需要回顾:
并发编程内存屏障
JUC的源码之前看的,现在得拾到拾到。
下面先从简单的,逐步突破:
问题解决
1.i++操作细节,和++i的区别
结论:是否先入栈再自增,还是先自增再入栈。
++i,是先自增再赋值,i++是先赋值再自增(从字面上讲,也是能理解的,这样就会多一个临时变量)。
i++ 要在内存中多创建一个临时变量,多执行一步占用内存更高。
前面是i++ 后面是++i
i++ 要多创建一个临时变量,所以在一样语义的时候,用i++比较好。
i++在字节码文件是这样的:
看大佬的解析锁的那部分,我就直接截取这边的i++
public class SyncCodeBlock {
public int i;
public void syncTask(){
//同步代码库
synchronized (this){
i++;
}
}
}
4: aload_0
5: dup
6: getfield #2 // Field i:I
9: iconst_1
10: iadd
11: putfield #2 // Field i:I
14: aload_1
我查阅了一下大概是这样的:
aload_0 从局部变量0中装载引用类型值
dup 复制栈顶部一个字长内容
getfield 从对象中获取字段
iconst_1 将int类型常量1压入栈
iadd 执行int类型的加法
putfield 设置对象中字段的值
aload_1 从局部变量1中装载引用类型值
关于:
int i = 1;
i = ++i + i++;
System.out.println(i);
结果是4
0: iconst_1 //将常量数字1入栈
1: istore_1 //出栈赋值给局部变量表i=1
2: iinc 1, 1 // 局部变量表i,自增加1 等于2
5: iload_1 // 2入栈
6: iload_1 //2再次入栈
7: iinc 1, 1 // 局部变量表i自增1,等于3
10: iadd // 操作数栈中的2+2相加等于4
11: istore_1 //出栈,替换局部变量表i的3为4。
————————————————
版权声明:本文为优快云博主「可乐多点冰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/u013541707/article/details/112513620
int i = 1;
// 1 + 3 + 3 + 5
i = i++ + ++i + i++ + ++i;
System.out.println(i);
/**
* 0: iconst_1 数值1入栈
* 1: istore_1 数值1出栈赋值给i
* 2: iload_1 i(1)入操作数栈
* 3: iinc 1, 1 i在局部变量表自增1,此时i=2
* 6: iinc 1, 1 i在局部变量表自增1,此时i=3
* 9: iload_1 i继续入栈,第二次为3
* 10: iadd 相加,与第一次栈中1和第二次的3相加为4,此时栈中为只有一个值且4
* 11: iload_1 又把局部变量表中的i=3入栈
* 12: iinc 1, 1 局部变量表中i为3自增1,变为了4
* 15: iadd 4+3等于7
* 16: iinc 1, 1 局部变量表中i为4自增1,变为了5
* 19: iload_1 i=5入操作数栈
* 20: iadd 与原本操作数栈中的7相加,等于12
* 21: istore_1 出栈返回给局部变量表中的i,即此时i从5变为了12
**/
结果是:12
以上就是i++和++i的底层分析,终极区别是,是否先入栈再自增,还是先自增再入栈。
https://blog.youkuaiyun.com/u013541707/article/details/112513620 这个作者讲的好好~
2. CAS面试需要什么程度?
CAS:Compare and Swap,比较并交换。CAS有3个操作数:内存值V、预期值A、要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。该操作是一个原子操作,被广泛的应用在Java的底层实现中。在Java CAS主要是由sun.misc.Unsafe这个类通过JNI调用CPU底层指令实现
3. [线程]java的线程状态以及如何新建线程
[线程]java的线程状态以及如何新建线程 : https://blog.youkuaiyun.com/pmdream/article/details/119868141
[线程]线程池的使用和7个参数的含义:https://blog.youkuaiyun.com/pmdream/article/details/119873615
4. [线程]操作系统线程是怎么切换的(用户态的内部切换)
https://blog.youkuaiyun.com/pmdream/article/details/119881080
5.[volitate]volatile和synchronized特点
https://blog.youkuaiyun.com/pmdream/article/details/107821238