并发编程概览 - 从 Lock 和 Synchronized 说起
前言
在 Java 程序员面试的时候,基础知识部分经常会被问到,Lock 和 Synchronized 的区别。其实这里只是一个入口,面试官如果感兴趣的化,会从这里切入,考察并发编程的整个知识体系。
我们也从这里开始,聊一下 Java 并发编程知识网络。
回答
接上面的问题,一般比较不错的回答是这样子的:
synchronized 是 Java 的关键字,在虚拟机层面,对象监视器来实现虚拟机的 lock 和 unlock 原子性操作,需要持有一个特定的锁。
lock 是 java concurrent 包下的接口。用它来做锁操作主要可以实现 可控制中断、可实现公平锁、可绑定多个条件的特性。java1.6 之前 lock 是比 syn 的效率高的。但是在 1.6 及以后经过锁优化之后,两者效率差不多了。锁优化包括:自旋与自适应、锁消除、锁粗话、轻量级锁、偏向锁。
所以在 1.6 以后,选择 lock 的原因只能是要实现更多的功能,而不是效率问题。
对 synchronized 关键字,要从虚拟机层面了解实现的原理。接下来的问题可能就是 Synchronized 在同步方法和同步代码块上的区别;锁升级的过程等等。
对 lock 关键字,需要知道 Java 在语言层面上是如何实现的,这里就会涉及到 lock 的实现,AQS,CAS 等概念,然后会问是否有过相关的实践,比如 CountDownLatch、Cyclicrrier 锁的使用、线程池的使用和原理之类的经典问题等等。
知识网络
现在我们再回过头来,梳理一下作为一名 Java 开发程序员需要掌握的并发编程相关的理论知识体系。这里我们是按照自下往上的顺序来了解的。
基础知识
初学 Java 都会接触的多线程编程,这也是当时 Java 语言的一大特色和优势,当然现在来看线程的粒度上的并发有些跟不上了。常见的问题有进程和线程的区别、创建线程的方式、线程的生命周期和状态转化、线程同步和线程通信等等。还有一些经典的实践:生产者消费者问题、银行家算法、多线程循环打印等等。
JMM 内存模型理论和 CPU 原子指令
和 Synchronized 相关的是 JMM 内存模型理论,工作内存和主内存的概念,可见性、重排序和原子性问题,内存屏障的概念等等
和 Lock 相关的是 CPU 缓存,CAS 相关指令等等。
Lock 相关应用,Synchronized 等 Java 关键字
AQS(AbstractQuenedSynchronizer 抽象队列式同步器)相关内容,unsafe,locksupport,一些常用的并发编程工具类(CountDownLatch,CyclicBarrier,Sepmopore……);Synchronized 锁升级过程,其它的关注字(volatile,final)及原理和应用。
线程池
常见的线程池类型,实现原理,Fork/Join 框架、CompletableFuture 等等。一个常见的问题是如何设置线程池大小/各项参数。
这里从网上摘了一个图片,基本上整个知识体系可以成‘#’的形状。
小结
这里 Java 并发编程的框架大概介绍完了,之后会就这些内容展开介绍。另外,开始提到了线程粒度的并发,并不足以支撑想当前互联网大厂的一些应用场景了,接下来“协程”、“管程”的概念就要出场,后续也会分享。
版权声明: 本文为 InfoQ 作者【追风少年】的原创文章。
原文链接:【http://xie.infoq.cn/article/6c96f0aecd03b667c643810e6】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论