1.JVM运行时数据区
分为线程共享区域(又分为方法区,堆内存)
线程独占区域(又分为虚拟机栈,本地方法栈,程序计数器)
2.多线程的可见性问题
变量加volatile关键字,代表此字段不需要被优化,不需要被缓存,
造成可见性问题的原因是JIT(JUST IN TIME即时编译器),jvm对程序的优化,对热点代码进行缓存,或者指令的重排序,有可能会影响最终执行结果,使用该关键字告诉底层jvm不需要被优化
3.可以在线程之间共享的内存称为共享内存或堆内存,所有实例字段,静态字段和数组元素都存在堆内存中
4.原子性(atomicInteger.incrementAndGet()多线程安全的i++)
指多线程操作对象过程中,对象不能被其他线程改变
jdk提供了JUC并发包下的Atomic类,底层是使用Unsafe类,Unsafe类中是一些native方法,native方法是非java实现的方法,底层是c++实现,可以直接操作内存,Unsafe的CAS机制,可以保证原子性.CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则返回V
5.jdk8之后LongAdder提供了更高效的i++
原理是将i分成好几个,然后不同线程操作不同的i.,最后再将结果累加,这种分而治之的思维,可以减少线程对同一资源的争抢,提高i++操作效率
6.atomicInteger.incrementAndGet()有什么缺点?
1.线程在争抢资源时,自旋+CAS,会消耗cpu,多个线程争抢资源
2.只能对单一数据实现原子性,无法对多个数据实现原子性
3.ABA问题(可以使用带版本号的原子变量解决)