前言
在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并发编程的框架大概介绍完了,之后会就这些内容展开介绍。另外,开始提到了线程粒度的并发,并不足以支撑想当前互联网大厂的一些应用场景了,接下来“协程”、“管程”的概念就要出场,后续也会分享。