简介
在暑期实习的过程遇到了大厂基本上都绕不开并发编程的问题,可以说并发编程是任何编程语言绝对重头的部分,不论是为了以后的面试还是自我的提升,学习并发编程都是必须的。希望通过本次的学习可以掌握:
1. Java并发的机制;
2. JVM中是如何支持并发的;
3. 学会并发编程的基础语法;
4. 加深对常用的关键字的理解;
5. 掌握一定的并发编程的技巧;
阅读书籍
《Java并发编程的艺术》
阅读前推荐:
- 对Java编程基础和面向对象设计熟悉;
- 对操作系统比较熟悉(线程相关概念);
- JVM了解一点。
正文部分
目录
chapter 1: 并发编程的挑战(本章)
chapter 2:Java并发机制的底层实现
并发编程的挑战
这部分主要介绍了在使用并发编程时一定会遇到的问题,也是我们在进行并发编程的时候会考虑的点。
1. 上下文切换
首先明确并发和并行的区别,这一点不再详细描述,OS课已经说烂掉了。
并发从CPU的角度来看,就是CPU为每个程序分配一定的时间片,程序使用完当前的时间片就会被挂起,进行上下文的切换,切换到别的程序的上下文,这样多个程序反复切换,使得在一段时间内,这些程序一起执行。
那么并发不可避免涉及到上下文的切换,线程的切换代价小,进程的代价大。所以本书在一开始抛出的问题其实是很有意义的:并发不一定会带来程序执行速度的提升,因为如果上下文切换的开销相当大,那么并发就会显得很鸡肋。。
ok,明确了问题所在,那么如何最大程度优化线程的切换呢?书中给出了一些建议:
- 无锁并发编程:多线程竞争锁会导致上下文的切换,尽量减少锁的使用;
- 使用CAS:Java的Atomic包使用CAS算法更新数据,不用加锁;
- 减少不必要的线程:当任务量不大时,不用创建太多线程,这样会使得很多线程处于等待状态。这一部分后面的案例有解释,为了执行一个任务,开辟多个线程,多个线程会频繁抢锁,引发上下文的切换。
- 协程:在单线程中实现多任务的调度。
2. 死锁问题
OS里面最经典的问题,如果上下文切换降低了效率,那么死锁是直接可以让系统无法正常运行。如何解决死锁呢?
- 避免在一个线程中同时获取多个锁;
- 避免一个在一个锁中占用多个资源;
- 使用定时锁
。lock.trtLock(timeout)
- 对数据库的操作的加锁和解锁必须在一个连接中完成。
3. 资源限制问题
不同的系统由于面对的业务场景不同,可能存在不同的瓶颈(网络、IO等),我认为作者值得是系统中存在某个瓶颈时引发的问题。作者是想告诉我们,在设计并发时,目光不应该放在代码本身,系统是一个整体,如果脱离系统只去考虑代码,那么可能对系统效率提升并不大。
总结
本章主要介绍了并发编程中一些挑战,为后面的系统讨论打下基础。