面时莫慌 | 并发编程有哪些挑战?

676 阅读3分钟

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

上文讲到,为了提高计算机资源的利用率,先驱们依次创造了操作系统、进程、线程、协程,这些技术通过时间片分配、上下文切换、多线程等原理实现了对资源利用的最大化。这篇文章来讲一下并发编程带来的挑战。

一、挑战

根据硬币有两面的原则(我编的,可以选择不相信),满足最大程度使用计算机资源,同时也带了许多技术上的挑战,包括但不限于:

  • 如何平衡上下文切换带来的资源的消耗,是不是线程越多,执行效率越高?
  • 多线程并发对同一资源的可见性、原子性,顺序性如何处理?
  • 为什么要有锁,如何有效地避免死锁?
  • 如何在有限的资源下,设计合适的线程,让程序运行的更快?

让我们带着这些问题,进一步学习并发编程。

二、上下文切换

我选择性的解答几个问题,其它问题在后续的文章一一解答。首先说说如何如何平衡上下文切换带来的资源的消耗,是不是线程越多,执行效率越高?

众所周知,CPU是通过分配相当短(一般是几十毫秒)的时间片给每个线程,按照一定的策略不停的切换执行的线程,以支持多线程并发执行。正是由于这样的方式,我们感觉这么多线程是同时执行的。

那么线程的上下文切换这个过程过程发生了哪些事情呢?很容易能想到的是,CPU调度一个线程任务停下来,启动另一个线程停下来,肯定是需要把前一线程执行过程中的状态保存下来,否则后面要重新切回这个线程,从何开始,如何执行呢?重点来啦,这样的上下文切换对性能的影响显而易见,因为保存和恢复上下文需要保存和恢复寄存器的数据,有些寄存器的数据量是很大的,操作这些数据开销也就非常大了,这是最直接的影响,其它消耗包括进程控制模块、用户堆栈以及共享存储区等。

上下文切换分为三种进程上下文、中断上下文、模式切换(用户态与内核态的切换),最后一种模式切换是一种特殊的上下文切换,因为它并没有经历过完整的上下文切换,只是经过了寄存器的上下文切换。

那么如何减少上下文切换呢?具体的方法有无锁并发编程、CAS算法、使用最少线程和使用协程,后面细讲吧。


哥佬倌,莫慌到走!觉好留个赞,探讨上评论。欢迎关注面试专栏面时莫慌 | Java并发编程,面试加薪不用愁。也欢迎关注我,一定做一个长更的好男人。