上周的面试中,被问及了几个关于Java并发编程的问题,自己回答的都不是很系统和全面,可以说是“头皮发麻”,哈哈。因此果断购入《Java并发编程的艺术》一书,学习后的体会是要想快速上手Java并发编程,最需要掌握的是线程、线程池概念的理解和Executor框架的使用。
Tip:
实践请见github-multiThread,不会介绍Java内存模型等更底层的内容。看看下图的“糙汉”身上错综复杂的线[程],愿通过学习,能化繁为简,[高效]的编出[高效]的多线程代码。
基本概念
在实践中,为了更好的利用资源提高系统整体的吞吐量,会选择并发编程。但由于上下文切换和死锁等问题,并发编程不一定能提高性能,因此如何合理的进行并发编程时本文的重点,接下来介绍关于锁最基本的一些知识(选学)。
volatile:轻量,保证共享变量的可见性,使得多个线程对共享变量的变更都能及时获取到。其包括两个子过程,将当前处理器缓存行的数据写回到系统内存,之后会使其他CPU里缓存了该内存地址的数据无效。
synchronized:相对重量,其包含3种形式,针对普通同步方法,锁是当前实例对象;针对静态同步方法,锁是当前类的Class对象;对于同步代码块,锁是Synchonize括号内配置的对象。此外,synchronize用的锁存在ava对象头中,编译后会插入类似
monitorenter, monitorexit
的代码。锁状态:包括无锁状态,偏向锁状态,轻量级锁状态,重量级锁状态。Tip,锁可以升级但不能降级。
Java实现原子操作:可以通过锁和循环CAS来实现原子操作,不过其也存在3个问题,包括ABA问题,通过版本号解决;循环时间长开销大,通过
pause
指令减少自旋带来的开销;只能保证一个共享变